线性表(不间断更新)
1.基本概念
线性表:n个数据类型相同元素的有限序列。(比如矩阵,数组,字符串,堆栈,队列等)。
特点:第一个元素无直接前趋,最后一个元素无直接后继,其余元素都有一个直接前趋和一个直接后继。
存储结构:线性存储结构,链式存储结构。
2.练习
(1)两个递增顺序表(顺序存储),la,lb,顺序插入顺序表lc中。
#include <stdio.h> #include <stdlib.h> #define SIZE 6 #define END 9999 #define CHARGE 0 typedef int ElemType; typedef struct list { ElemType elem[15]; int last; } SeqList; void initList(SeqList *l) { int index = 0; int midleVarile = 0; printf("if you want to exit please input 9999\n"); printf("please input intger:"); while(1) { scanf("%d", &midleVarile); if(midleVarile == END) { break; } else { l->elem[index] = midleVarile; } index++; // fflush(stdin); } l->last = index; } void mergeList(SeqList *l1, SeqList *l2, SeqList *l3) { int index1 = 0; int index2 = 0; int index3 = 0; int midleInt = 0; while((index1 != (l1->last)) && (index2 != (l2->last))) { if(l1->elem[index1] <= l2->elem[index2]) { midleInt = l1->elem[index1]; l3->elem[index3] = midleInt; index1++; index3++; } else { midleInt = l2->elem[index2]; l3->elem[index3] = midleInt; index2++; index3++; } } if(index1 == (l1->last)) { for( ; index2 != (l2->last); index2++, index3++) { l3->elem[index3] = l2->elem[index2]; } } else { for(; index1 != (l1->last); index1++, index3++) { l3->elem[index3] = l1->elem[index1]; } } l3->last = l1->last + l2->last; } void outList(SeqList *l) { int index = 0; int i; for(i = 0; i < l->last; i++) { printf("%d ", l->elem[i]); } } int main() { SeqList l1; SeqList l2; SeqList l3; initList(&l1); initList(&l2); mergeList(&l1, &l2, &l3); outList(&l3); }
(2)代码功能如下,后期会继续增加,当作复习用。
1 #include <stdio.h> 2 #include <stdlib.h> 3 4 #define OK 1 5 #define ERROR 0 6 #define OVERFLOW -2 7 8 typedef int ElemType; 9 10 typedef struct Node 11 { 12 ElemType data; 13 struct Node *next; 14 } Node, *LinkList; 15 16 // 创建新链表 17 Node * NewLinkList() 18 { 19 Node *node = (Node *)malloc(sizeof(Node)); 20 node->next = NULL; 21 return node; 22 } 23 24 //初始化链表 25 void InitLinkList(LinkList l) 26 { 27 // Node * l1; 28 int midleInt = 0; 29 30 printf("please input intger end with 9999:"); 31 32 while(midleInt != 9999) 33 { 34 scanf("%d", &midleInt); 35 l->next = (Node *)malloc(sizeof(Node)); 36 l = l->next; 37 l->next = NULL; 38 l->data = midleInt; 39 } 40 } 41 42 //得到链表的长度 43 unsigned int getListLength(LinkList l) 44 { 45 int lLength = 0; 46 47 l = l->next; 48 49 if(l == NULL) 50 return 0; 51 52 while(l != NULL) 53 { 54 lLength++; 55 l = l->next; 56 } 57 58 return lLength; 59 } 60 61 //链表的反转 62 LinkList ReverseList(LinkList l) 63 { 64 LinkList l1 = NewLinkList(); 65 LinkList l2; 66 LinkList l3 = l; 67 68 69 if((l->next == NULL) || (l->next->next == NULL)) 70 return l; 71 72 l = l->next; 73 74 while(l != NULL) 75 { 76 l2 = l1->next; 77 l3 = l->next; 78 l1->next = l; 79 l->next = l2; 80 l = l3; 81 } 82 83 return l1; 84 } 85 86 //链表清空 87 void LinkListClear(LinkList l) 88 { 89 l->next = NULL; 90 } 91 92 //链表是否为空 93 int LinkListisEmpty(LinkList l) 94 { 95 if(l->next == NULL) 96 return 1; 97 else 98 return 0; 99 } 100 101 //链表遍历 102 void LinkListTraverse(LinkList l) 103 { 104 // LinkList l1 = l; 105 l = l->next; 106 107 while(l != NULL) 108 { 109 printf("%d ", l->data); 110 111 l = l->next; 112 } 113 printf("\n"); 114 } 115 116 int main(void) 117 { 118 LinkList l = NewLinkList(); 119 InitLinkList(l); 120 LinkListTraverse(l); 121 l = ReverseList(l); 122 LinkListTraverse(l); 123 }
后面会继续增加
//算法思想:定义两个节点指针,让第一个节点指针首先后移k个节点,然后让另一个指针和第一个指针同时后移,知道第一个指针到达尾部。
//注意:当链表节点总数小于k时,或者k为0时候,或者链表为空时候。
1 //查找单链表中倒数第k个节点 2 Node * GetAKNode(LinkList l, int k) 3 { 4 Node *l1 = l; 5 Node *l2 = l; 6 LinkList l3 = l; 7 int nodeLength; 8 9 l3 = l3->next; 10 nodeLength = getListLength(l3); 11 12 if((l3 == NULL) || (nodeLength < k) || (k == 0)) 13 return NULL; 14 15 while(k) 16 { 17 k--; 18 l1 = l1->next; 19 } 20 21 while(l1 != NULL) 22 { 23 l1 = l1->next; 24 l2 = l2->next; 25 } 26 27 return l2; 28 } 29
//算法思想:定义两个指针,第一个节点后移一个单位,第二个节点后移两个单位,当第二个节点到达尾部的时候,第一个节点指向中间节点的位置。
//注意:当只有1个节点,或者,为空的时候,直接返回头节点。 30 //获得单链表中间节点 31 Node *GetMNode(LinkList l) 32 { 33 Node *l1 = l; 34 Node *l2 = l; 35 36 if((l->next == NULL) || (l == NULL)) 37 return l; 38 39 while(l1 != NULL) 40 { 41 l1 = l1->next; 42 l2 = l2->next; 43 44 if(l1 != NULL) 45 { 46 l1 = l1->next; 47 } 48 } 49 50 return l2; 51 }
//判断单链表是否有环
//算法思想:两个指针,快的每次走两步,慢的,每次走一步,如果相交则有环,快的走到空,则无环。
1 int hasCircle(LinkList l) 2 { 3 Node * l1 = l; 4 Node * l2 = l; 5 6 if(l->next == NULL) 7 return 0; 8 9 while(l1 == NULL) 10 { 11 l1 = l1->next; 12 l2 = l2->next; 13 14 if(l1 != NULL) 15 l1 = l1->next; 16 17 if(l1 == l2) 18 return 1; 19 } 20 21 return 0; 22 }
//寻找两个链表的交点
//算法思想:招到较长的链,让较长的链的长度减去较短链的长度,然后让较长链的指针后移到和较短链相同长度的位置,然后同时后移,每次作比较,相同则为交点。
1 Node *GetFirstCommonNode(LinkList l1, LinkList l2) 2 { 3 Node *l3 = l1; 4 Node *l4 = l2; 5 int i3 = 0; 6 int i4 = 0; 7 8 if(l1->next == NULL || l2->next == NULL) 9 return NULL; 10 11 l3 = l3->next; 12 l4 = l4->next; 13 l1 = l1->next; 14 l2 = l2->next; 15 16 while(l3 != NULL) 17 { 18 i3++; 19 l3 = l3->next; 20 } 21 22 while(l4 != NULL) 23 { 24 i4++; 25 l4 = l4->next; 26 } 27 28 if(i3 >= i4) 29 { 30 i3 = i3 - i4; 31 32 while(i3) 33 { 34 i3--; 35 l1 = l1->next; 36 } 37 } 38 else 39 { 40 i4 = i4 - i3; 41 42 while(i4) 43 { 44 i4--; 45 l2 = l2->next; 46 } 47 } 48 49 while(l1 != l2) 50 { 51 l1 = l1->next; 52 l2 = l2->next; 53 } 54 55 return l1; 56 }
//删除data为k的节点,要求时间复杂度为0(1) //算法思想:先找到该节点,把后一个节点复制到本节点,删除后一个节点,如果要删除的节点是最后一个,则笨办法遍历到最后一个节点的前一个节点,删除。 void Delete(LinkList l, int k) { Node * l1 = l; if(l->next == NULL) return; l1 = l->next; while(l1 != NULL) { if(l1->data == k) { if(l1->next == NULL) { while(1) { if(l->next == l1) { l->next = NULL; return ; } l = l->next; } } l1->data = l1->next->data; l1->next = l1->next->next; return ; } l1 = l1->next; } }
//双向链表的建立
#include <stdio.h> #include <stdlib.h> typedef int ElemType; typedef struct Node { ElemType data; struct Node *pre; struct Node *next; }DList, *DListHead; void creat(DListHead *head) { int x = 0; DListHead l; DListHead l1; *head = (DList *)malloc(sizeof(DList)); l = *head; l->pre = NULL; l->data = x; while(x != -1) { scanf("%d", &x); l->next = (DListHead)malloc(sizeof(DList)); l1 = l->next; l1->data = x; l1->next = NULL; l1->pre = l; l = l->next; } l = l1->pre ; free(l1); l->next = NULL; } void print(DListHead *head) { DListHead head1 = *head; while(head1 ->next != NULL) { printf("%d ",head1->data); head1 = head1->next; } printf("\n"); while(head1->pre != NULL) { printf("%d ", head1->data); head1 = head1->pre; } } int main() { DListHead head; creat(&head); print(&head); }