一、数据结构与算法
时间复杂度O(n)
空间复杂度
二、顺序表及其应用:
- 顺序查找算法:从顺序表的一端开始顺序扫描,将给定的k值一次与顺序表中各元素的关键字比较
int SeqSearch(List L,KeyType k) { //在顺序表L中顺序查找其关键字等于k的元素,若找到返回该元素的位置,否则为0 L.r[0].key=k; //0号单元做为监视哨 int i=L.lengrh; while(L.r[i].key!=k) i--; retutn i; }
ASL=(求和公式1到n)PiCi = (n+1)/2
- 二分查找算法(折半查找):要求待查找的数据元素必须按关键字的大小有序排列的顺序表
int BinSrch(List *L,KeyType k) { //在顺序表L中二分查找其关键字等于k的元素,若找到返回该元素的位置 int low,high,mid,i; low=i=0; high=L->length-1; //置区间初值 while(low<=high) { mid=(low+high)/2; if (k == L->r[mid].key) //找到待查元素 { i = mid; break; } else if (k < L->r[mid].key) high = mid - 1; //未找到,则在前半去查找 else low = mid + 1; //继续在后半区查找 } retutn i; }
ASL=log2(n+1)-1=log2n
- 分块查找算法:索引顺序查找,每个索引项记录该块的起始位置,以及该块中的最大关键字(最小)。索引表按关键字有序排列
思想:(1)应用二分查找算法或简单顺序查找算法,将给定值key与索引表中的关键字比较,以确定待查元素所在的块
(2)应用简单顺序查找算法,在相应块内查找关键字为key的数据元素
ASL=log2(n/s+1)+s/2
- 三种查找算法性能比较:简单顺序查找算法效率最低,其次是分块查找,而二分查找算法的时间性能最好。
三、链表及其应用
单链表的数据结构
- 置空表:当单链表为空表时,表中没有任何元素,仅有头结点,即L->next=NULL
- 求表长:求链表的长度是求链表中不包括头结点在内的结点个数
1 List *LLsetnull(List *L) //置空表 2 { 3 L->next=NULL; 4 return L; 5 } 6 List *LLlength(List *L)//求表长 7 { 8 List *p; 9 p=L->next; 10 int n=0; 11 while(p!=NULL) 12 { 13 n++; 14 p=p->next; 15 } 16 return n;17 }
- 创建单链表头、尾插法:头插法新结点总是插入到头结点之后,尾插法将新结点插入到当前链表的表尾。
1 LinkList* CreatlistH() //头插法 2 { 3 LinkList* L, * head, * S; 4 char ch; 5 L = (LinkList*)malloc(sizeof(LinkList)); 6 head = L; 7 L->next = NULL; //建空单链表 8 ch = getchar(); 9 while (ch != '#') 10 { 11 S= (LinkList*)malloc(sizeof(LinkList)); 12 S->data = ch; 13 S->next = L->next; 14 L->next = S; 15 ch = getchar(); 16 } 17 return head; 18 } 19 LinkList* CreatlistR() //尾插法 20 { 21 LinkList* L, * R, * S; 22 char ch; 23 L = (LinkList*)malloc(sizeof(LinkList)); 24 L->next = NULL; //建空单链表 25 R = L; 26 while (ch != '#') 27 { 28 S = (LinkList*)malloc(sizeof(LinkList)); 29 S->data = ch; 30 S->next = NULL; //申请结点并赋值 31 R->next = S; 32 R = S; 33 ch = getchar(); 34 } 35 return L; 36 }
- 插入、删除、查找:
1 LinkList* Locate(LinkList* L, DataType x) //单链表按值查找算法 2 {//在带头结点的单链表L中查找其结点值等于x的结点,找到返回p否则为空 3 LinkList* p; 4 p = L->next; //从第一个结点比较 5 while (p != NULL) 6 { 7 if (p->data != x) 8 p = p->next; 9 else break; //找到,退出循环 10 } 11 return p; 12 } 13 void Linksert(LinkList* L,int i,DataType x) //在带头结点的单链表L中第i个位置插入值为x的新结点 14 { 15 LinkList* p, * s; 16 int j = 0; 17 p = L; 18 while (p != NULL&&j<i-1) 19 { 20 p = p->next; 21 j++; 22 } 23 if (p == NULL) printf("序号错"); 24 else 25 { 26 s= (LinkList*)malloc(sizeof(LinkList)); 27 s->data = x; 28 s->next = p->next; //不可调换位置 29 p->next = s; 30 } 31 } 32 void Ldelete(LinkList* L, int i) //在带头结点的单链表L中删除第i个结点 33 { 34 LinkList* p, * s; 35 int j = 0; 36 p = L; 37 while (p != NULL && j < i - 1) 38 { 39 p = p->next; 40 j++; 41 } //先找到第i-1个结点的存储位置,使指针p指向它 42 if (p != NULL && p->next != NULL) //第i-1个结点和第i个结点均存在 43 { 44 s = p->next; //s指向要删除的位置 45 p->next = s->next; 46 free(s); //释放空间 47 } 48 }
四、堆栈及其应用
- 定义:先进后出,入栈出栈都是在栈顶进行操作。
- 顺序栈置空:top为0表示还有一个元素只有为-1才是空栈
1 SeqStack* InitStack(SeqStack* S) //置空,top=-1表示栈空 2 { 3 S->top = -1; 4 return S; 5 }
- 顺序栈入栈、出栈:栈顶位置top所指示的元素为栈顶元素
1 void Push(SeqStack* S,DataType x) //入栈 2 { 3 if (S->top <= maxlen - 1 && S->top >= 0) 4 { 5 S->top++; 6 S->data[S->top] = x; 7 } 8 else printf("error"); 9 } 10 void Pop(SeqStack* S) //出栈 11 { 12 if (S->top >= 0) 13 S->top--; 14 else printf("error"); 15 }
- 链栈置空、入栈、出栈:LS为栈顶指针
1 LinkStack* Push(LinkStack* LS,DataType x) //入栈 2 { 3 LinkStack* p; 4 p = (LinkStack*)malloc(sizeof(LinkStack * LS)); 5 p->data = x; 6 p->next = LS; //将该结点插入到链栈头部 7 LS = p; 8 return LS; 9 } 10 LinkStack* Pop(LinkStack* LS)//出栈 11 { 12 LinkStack* u; 13 u = LS; 14 LS = u->next; 15 free(u); 16 return LS; 17 } 18 LinkStack* InitStack(LinkStack* LS) //置空栈 19 { 20 while (LS != NULL) 21 LS=Pop(LS); //依次出栈 22 return LS; 23 }
五、队列及其应用
- 循环队列:入队、出队、队空、队满:先进先出
1 int Full(Queue* Q) 2 { 3 if (Q->front == (Q->rear + 1) % max) return 1; 4 else return 0; 5 } 6 int Empty(Queue* S) 7 { 8 if (S->front == S->rear) return 1; 9 else return 0; 10 } 11 void Add(Queue* L, int x) 12 { 13 if (!Full(L)) //若队不满则入队 14 { 15 L->rear = (L->rear + 1) % max; 16 L->data[L->rear] = x; 17 } 18 else printf("队满"); 19 } 20 void Delete(Queue* Q) 21 { 22 if (!Empty(Q)) //弱队不空则出队 23 Q->front = (Q->front + 1) % max; 24 else printf("队空"); 25 }
- 链队列:设计头指针尾指针
1 int Empty(LinkQueue* q) 2 { 3 if (q->front == q->rear) return 1; 4 else return 0; 5 } 6 LinkQueue* Add(LinkQueue* L, int x) //将元素x入队列 7 { 8 Link* p; 9 p= (Link*)malloc(sizeof(Link)); //建立新结点存放x 10 p->data = x; 11 p->next = NULL; //尾插法 12 L->rear->next = p; 13 L->rear = p; 14 return L; 15 } 16 LinkQueue* Delete(LinkQueue* S) 17 { 18 Link* p; 19 if (!Empty(S)) //队不空出队 20 { 21 p = S->front->next; 22 S->front->next = p->next; 23 if (p->next == NULL) //如果队的长度为1则改变队尾指针 24 S->rear = S->front; 25 free(p); 26 return S; 27 } 28 else printf("队空"); 29 }