1.数据结构(DS)是什么?
数据结构是数据之间的组织架构,数据结构的表现形式:顺序表seqlist、链表list、树tree、图graph、排序sort、搜索search;最终目标是为搜索服务,快速准确的查找想要的数据。
2.如何衡量一个算法的好坏?
时间复杂度和空间复杂度
3.数据结构的分类
(1)顺序结构(线性结构也叫线性表)
顺序表 链表 队列 栈
(2)非线性结构(关联结构)
树、图
(3)排序
(4)搜索
4.线性结构特点:除了第一个元素和最后一个元素之外,其与元素必须有且仅有一个前驱和后继
顺序表
注意:头删的时候需要把后面的数据往前移动,注意越界问题; 头插的时候需要把数据往后移动一个,空出位置来
//Common.h
#include <stdio.h>
#include <stdlib.h>
#include <assert.h>
#include <stdbool.h>
#include <memory.h>
#include <vld.h>
typedef int SLDataType;
void Swap(SLDataType* x, SLDataType* y)
{
SLDataType temp = *x;
*x = *y;
*y = temp;
}
//main.cpp
#include "seqlist.h"
#pragma warning (disable:4996)
int main()
{
Seqlist list;
SeqListInit(&list);
int pos=0;
int select = 0;
int item = 0;
bool flag;
while (1){
printf("****************************************\n");
printf("** 0.exit_system 1.show_list **\n");
printf("** 2.push_back 3.pop_back **\n");
printf("** 4.push_front 5.pop_front **\n");
printf("** 6.insert_pos 7.insert_val **\n");
printf("** 8.erase_pos 9.earse_val **\n");
printf("** 10.length 11.find **\n");
printf("** 12.sort 13.reverse **\n");
printf("** 14.front 15.back **\n");
printf("** 16.capacity 17.clear **\n");
printf("** 18.binary_find **\n");//二分查找必须先排序 删除所有(1 2 2 2 3)重复的都删除
printf("****************************************\n");
printf("请输入你要选择的选项:");
scanf("%d",&select);
if (select == 0)
{
printf("系统正在退出,byebye!\n");
system("pause");
break;
}
switch (select)
{
case 1:
SeqListShow(&list);
break;
case 2:
printf("请输入你要插入的数据<以-1结束>:");
while (scanf("%d", &item), item != -1)
{
SeqListPushBack(&list, item);
}
printf("尾部插入数据成功!\n");
break;
case 3:
SeqListPopBack(&list);
printf("尾部删除数据成功!\n");
break;
case 4:
printf("请输入你要插入的数据<以-1结束>:");
while (scanf("%d", &item), item != -1)
{
SeqListPushFront(&list, item);
}
printf("头部插入数据成功!\n");
break;
case 5:
SeqListPopFront(&list);
printf("头部删除数据成功!\n");
break;
case 6:
printf("请输入要插入的位置:");
scanf("%d", &pos);
printf("请输入你要插入的元素:");
scanf("%d", &item);
flag=SeqListPush_Pos(&list, pos, item);
if (flag)
{
printf("插入数据成功.......\n");
}
else
{
printf("插入数据失败.......\n");
}
break;
case 7:
printf("请输入你要插入的元素:");
scanf("%d", &item);
flag=SeqListPush_Val(&list, item);
if (flag)
{
printf("插入数据成功.......\n");
}
else
{
printf("插入数据失败.......\n");
}
break;
case 8:
printf("请输入要删除的元素的位置:");
scanf("%d", &pos);
SeqListPop_Pos(&list,pos);
break;
case 9:
printf("请输入要删除的元素的值:");
scanf("%d", &item);
SeqListPop_Val(&list, item);
break;
case 10:
printf("length=%d\n",SeqListLength(&list));
break;
case 11:
printf("请输入你要查找的元素:");
scanf("%d", &item);
pos=SeqList_Find(&list,item);
if (pos == -1)
{
printf("查找失败!\n");
}
else {
printf("查找成功,在%d的位置", pos);
}
break;
case 12:
SeqListSort(&list);
printf("顺序表排序成功......\n");
break;
case 13:
SeqListReverse(&list);
printf("转置完成.\n");
break;
case 14:
printf("表头元素为:%d\n",SeqListFront(&list));
break;
case 15:
printf("表尾元素为:%d\n",SeqListBack(&list));
break;
case 16:
printf("capacity=%d\n", SeqList_Capacity( &list));
break;
case 17:
SeqListClear(&list);
break;
case 18:
SeqListSort(&list);
printf("请输入你要查找的元素:");
scanf("%d", &item);
pos=SeqList_Find_Binary(& list,item);
if (pos == -1)
{
printf("查找失败!\n");
}
else {
printf("查找成功,在%d的位置", pos);
}
break;
default:
printf("命令出错,请重新输入......\n");
break;
}
system("pause");
system("cls");
}
return 0;
}
//seqlist.h
#include "Common.h"
#define SEQLIST_SIZE 8
typedef struct Seqlist{
SLDataType* base;//数组
size_t size;//底层大小
size_t capacity;//元素个数
}Seqlist;
//声明
void SeqListInit(Seqlist* list);//初始化
void SeqListPushBack(Seqlist* list,SLDataType x);//尾插
void SeqListPopBack(Seqlist* list);//尾删
void SeqListPushFront(Seqlist* list,SLDataType x);//头插
void SeqListPopFront(Seqlist* list);//头删
bool SeqListPush_Pos(Seqlist* list,int pos,SLDataType x);//按位置插入
void SeqListPop_Pos(Seqlist* list,int pos);//按位置删除
bool SeqListPush_Val(Seqlist* list,SLDataType val);//按值插入
void SeqListPop_Val(Seqlist* list, SLDataType val);//按值删除
void SeqListShow(Seqlist* list);//show
SLDataType SeqListFront(Seqlist* list);//首元素
SLDataType SeqListBack(Seqlist* list);//尾元素
size_t SeqListLength(Seqlist* list);//顺序表的长度
size_t SeqList_Capacity(Seqlist* list);//顺序表的底层大小
void SeqListSort(Seqlist* list);//顺序表的排序
void SeqListReverse(Seqlist* list);//顺序表的逆置
int SeqList_Find(Seqlist* list,SLDataType key);//查找
int SeqList_Find_Binary(Seqlist* list,SLDataType key);//二分查找法
void SeqListClear(Seqlist* list);//顺序表的清空
void SeqListDestroy(Seqlist* list);//销毁顺序表
//实现
bool _Inc(Seqlist* list, size_t new_capacity)
{
assert(list != NULL&&new_capacity > list->capacity);
SLDataType* new_base = (SLDataType*)realloc(list->base, sizeof(SLDataType)*new_capacity);
if (new_capacity == NULL)
{
return false;
}
list->base = new_base;
list->capacity = new_capacity;
return true;
}
bool isFull(Seqlist* list)
{
return list->capacity == list->size;
}
bool isEmpty(Seqlist* list)
{
return list->size == 0;//数组为空
}
void SeqListInit(Seqlist* list)
{
assert(list!=NULL);
list->capacity = SEQLIST_SIZE;
list->size = 0;
//申请空间
list->base = (SLDataType *)malloc(list->capacity*sizeof(SLDataType));
}
void SeqListPushBack(Seqlist* list, SLDataType x)
{
assert(list!=NULL);
//要判断是否满了
if (isFull(list))
{
printf("顺序表已满,不能插入!\n");
return;
}
list->base[list->size] = x;
list->size++;
}
void SeqListPopBack(Seqlist* list)
{
assert(list!=NULL);
if (isEmpty(list))
{
printf("顺序表为空,不能删除!\n");
return;
}
list->size--;
}
void SeqListPushFront(Seqlist* list, SLDataType x)
{
assert(list!=NULL);
size_t i = list->size;//该位置没有元素 这里得注意
for (; i >0; i--)
{
list->base[i] = list->base[i - 1];
}
list->base[0] = x;
list->size++;
}
void SeqListPopFront(Seqlist* list)
{
assert(list!=NULL);
//如果为空
if (isEmpty(list))
{
printf("顺序表为空,不能进行删除!\n");
return;
}
size_t i = 0;
for (; i < list->size; i++)
{
list->base[i] = list->base[i + 1];
}
list->size--;
}
//按位置插入
bool SeqListPush_Pos(Seqlist* list,int pos,SLDataType x)
{
assert(list!=NULL);
//如果满了或二次空间申请失败 注意只有第一个条件成立时 第二个条件才会执行
if (isFull(list) && !_Inc(list,( list->capacity) * 2))
{
printf("顺序表已满,%d不能在%d位置插入!\n",x,pos);
return false;
}
//如果要插入的位置超过size 就是不合法的
if (pos<0 || pos>list->size)
{
printf("要插入的位置不合法,%d不能在%d位置插入!\n", x, pos);
printf("请重新输入!\n");
return false;
}
size_t i = list->size;
for (; i >pos; i--)
{
list->base[i] = list->base[i - 1];
}
list->base[pos] = x;
list->size++;
return true;
}
//按位置删除
void SeqListPop_Pos(Seqlist* list,int pos)
{
assert(list!=NULL);
//如果为空
if (isEmpty(list))
{
printf("顺序表为空,不能进行删除!\n");
return;
}
if(pos<0 || pos>list->size)
{
printf("要删除的位置不合法,不能删除该位置\n");
return;
}
int i;
for (i=pos; i < list->size; i++)
{
list->base[i] = list->base[i + 1];
}
list->size--;
}
//按值插入
bool SeqListPush_Val(Seqlist* list,SLDataType val)
{
assert(list!=NULL);
if (isFull(list)&&!_Inc(list,list->capacity*2))
{
printf("顺序列表已满,不能插入!\n");
return false;
}
size_t end = list->size-1 ;
while (end >= 0 && val < list->base[end])
{
list->base[end ] = list->base[end-1];
end--;
}
list->base[end+1] = val;
list->size++;
return true;
}
//按值删除
void SeqListPop_Val(Seqlist* list,SLDataType val)
{
assert(list!=NULL);
int pos = SeqList_Find(list, val);
if (pos == -1)//没有找到
{
return;
}
SeqListPop_Pos(list, pos);
}
void SeqListShow(Seqlist* list)
{
assert(list);
if (isEmpty(list))
{
printf("顺序表为空,请输入数据!\n");
return;
}
for (size_t i = 0; i < list->size; i++)
{
printf("%d ", list->base[i]);
}
printf("\n");
}
SLDataType SeqListFront(Seqlist* list)
{
assert(list != NULL);
if (isEmpty(list))
{
printf("顺序表已空,不能取表头数据.\n");
return -1;
}
return list->base[0];
}
SLDataType SeqListBack(Seqlist* list)
{
assert(list != NULL);
if (isEmpty(list))
{
printf("顺序表已空,不能取表尾数据.\n");
return -1;
}
return list->base[list->size];
}
size_t SeqListLength(Seqlist* list)
{
return list->size;
}
size_t SeqList_Capacity(Seqlist* list)
{
return list->capacity;
}
void SeqListSort(Seqlist* list)
{
assert(list != NULL);
size_t i = 0;
for (; i < list->size-1; ++i)
{
size_t j = 0;
for (; j < list->size - i - 1; ++j)
{
if (list->base[j] > list->base[j + 1])
{
Swap(&list->base[j], &list->base[j + 1]);
}
}
}
}
int SeqList_Find(Seqlist* list,SLDataType key)
{
assert(list != NULL);
int pos = 0;
while (pos < list->size&&key != list->base[pos])
{
pos++;
}
//走完 找不到
if (pos == list->size)
{
pos = -1;
}
//走完能找到或者走完找不到
return pos;
}
void SeqListReverse(Seqlist* list)
{
assert(list!=NULL);
//边界条件
if (list->size == 1)
{
return;
}
int start = 0;
int end = list->size - 1;
while (start < end)
{
Swap(&list->base[start], &list->base[end]);
start++;
end--;
}
}
int SeqList_Find_Binary(Seqlist* list,SLDataType key)
{
assert(list != NULL);
if (isEmpty(list))
{
return -1;
}
size_t start = 0;
size_t end = list->size-1;
size_t mid;
while (start <= end)
{
mid = (start + end) / 2;
if (key == list->base[mid])
{
return mid;
}
else if(key>list->base[mid]){
start = mid + 1;
}
else
{
end = mid - 1;
}
}
return -1;
}
void SeqListClear(Seqlist* list)
{
assert(list != NULL);
list->size = 0;
}
void SeqListDestroy(Seqlist* list)
{
assert(list != NULL);
free(list->base);
list->base = NULL;
list->capacity = list->size = 0;
}