slist.h
1 #ifndef __SLIST_H__ 2 #define __SLIST_H__ 3 4 #include<cstdio> 5 #include<malloc.h> 6 #include<assert.h> 7 typedef int ElemType; 8 typedef struct Node { //定义单链表中的结点信息 9 ElemType data; //结点的数据域 10 struct Node *next; //结点的指针域 11 }Node,*PNode; 12 typedef struct List { //定义单链表的链表信息 13 PNode first; //first指向单链表中的第一个结点 14 PNode last; //last指向单链表中的最后一个结点 15 size_t size; //记录单链表中的结点个数 16 }List; 17 18 void InitList(List *list);//初始化单链表 19 void push_back(List *list, ElemType x);//在单链表的末尾插入元素 20 void push_front(List *list, ElemType x);//在单链表的头部插入元素 21 void show_list(List *list);//打印单链表 22 void pop_back(List *list);//删除单链表的最后一个元素 23 void pop_front(List *list);//删除单链表的第一个元素 24 void insert_val(List *list, ElemType val);//将数据元素插入到单链表中(要求此时单链表中的数据元素顺序排列) 25 Node* find(List *list, ElemType x);//查找单链表中数据值为x的结点 26 int length(List *list);//求单链表的长度 27 void delete_val(List *list, ElemType x);//按值删除单链表中的某个数据元素 28 void sort(List *list);//对单链表进行排序 29 void reverse(List *list);//逆置单链表 30 void clear(List *list);//清除单链表 31 void destroy(List *list);//摧毁单链表 32 33 #endif //__SLIST_H__
slist.cpp
1 #include"slist.h" 2 3 void InitList(List *list) { 4 list->first = list->last = (Node*)malloc(sizeof(Node)); //头结点 5 assert(list->first != NULL); 6 list->first->next = NULL; 7 list->size = 0; 8 } 9 10 void push_back(List *list, ElemType x) { 11 //step 1:创建一个新的结点 12 Node *s = (Node*)malloc(sizeof(Node)); 13 assert(s != NULL); 14 s->data = x; 15 s->next = NULL; 16 //step 2:将新结点插入单链表的表尾 17 list->last->next = s; 18 list->last = s; 19 //step 3:更新单链表的长度 20 list->size++; 21 } 22 23 void push_front(List *list, ElemType x) { 24 //step 1:创建一个新的结点 25 Node *s = (Node*)malloc(sizeof(Node)); 26 assert(s != NULL); 27 s->data = x; 28 s->next = NULL; 29 //step 2:将新结点插入单链表的表头 30 s->next = list->first->next; 31 list->first->next = s; 32 //step 3:判断插入的结点是否是单链表的第一个结点,若是更新链表的尾指针 33 if (list->size == 0) 34 list->last = s; 35 //step 4:更新单链表的长度 36 list->size++; 37 } 38 39 void show_list(List *list) { 40 //step 1:指针p指向单链表的第一个结点 41 Node *p = list->first->next; 42 //step 2:循环打印结点的信息 43 while (p != NULL) { 44 printf("%d->", p->data); 45 p = p->next; 46 } 47 printf("Nul. "); 48 49 } 50 51 void pop_back(List *list) { 52 //step 1:判断单链表是否为空 53 if (list->size == 0) return; 54 //step 2:定义指针p使其指向目标结点的前一个结点 55 Node *p = list->first;//从头结点开始 56 while (p->next != list->last) 57 p = p->next; 58 //step 3:删除目标结点 59 free(list->last); 60 list->last = p; 61 list->last->next = NULL; 62 //step 4:更新单链表的长度 63 list->size--; 64 } 65 66 void pop_front(List *list) { 67 //step 1:判断单链表是否为空 68 if (list->size == 0) return; 69 //step 2:定义指针p使其指向目标结点的前一个结点 70 Node *p = list->first->next; 71 //step 3:删除目标结点 72 list->first->next = p->next; 73 free(p); 74 //step 4:判断删除的结点是否是单链表的最后一个结点,若是则更新单链表的尾指针 75 if (list->size == 1) 76 list->last = list->first; 77 //step 4:更新单链表的长度 78 list->size--; 79 } 80 81 void insert_val(List *list, ElemType x) { 82 //step 1:创建一个新的结点 83 Node *s = (Node*)malloc(sizeof(Node)); 84 assert(s != NULL); 85 s->data = x; 86 s->next = NULL; 87 //step 2:定义指针p使其指向待插入位置的前一个结点 88 Node *p = list->first;//从头结点开始 89 while (p->next != NULL && p->next->data < s->data) 90 p = p->next; 91 //step 3:判断结点的待插入位置是否是表尾,若是则更新单链表的尾指针 92 if (p->next == NULL) 93 list->last = s; 94 //step 4:插入结点 95 s->next = p->next; 96 p->next = s; 97 //step 5:更新单链表长度 98 list->size++; 99 } 100 101 Node* find(List *list, ElemType x) { 102 //step 1:指针p指向单链表的第一个结点 103 Node *p = list->first->next; 104 //step 2:按照循环顺序查找链表结点 105 while (p != NULL && p->data != x) 106 p = p->next; 107 return p; 108 } 109 110 int length(List *list) { 111 return list->size; 112 } 113 114 void delete_val(List *list, ElemType x) { 115 //step 1:判断单链表是否为空 116 if (list->size == 0) return; 117 //step 2:确定结点在单链表中的位置,并判断其是否存在于单链表中 118 Node *p = find(list, x); 119 if (p == NULL) { 120 printf("要删除的数据不存在! "); 121 return; 122 } 123 //step 3:判断结点位置是否是表尾 124 if (p == list->last)//是表尾 125 pop_back(list); 126 else {//不是表尾 127 Node *q = p->next; 128 p->data = q->data; 129 p->next = q->next; 130 free(q); 131 list->size--; 132 } 133 } 134 135 void sort(List *list) { 136 //step 1:判断单链表中的结点数是否为0或1 137 if (list->size == 0 || list->size == 1) return; 138 //step 2:将单链表中第一个结点之后的链表部分截出,方便重新按顺序插入链表之中 139 Node *s = list->first->next; // 指针s指向单链表的第一个节点 140 Node *p = s->next;//q指向s后面的结点 141 list->last = s;//单链表的尾指针指向单链表的第一个结点 142 list->last->next = NULL;//截断链表 143 //step 3:将截出的链表中的结点根据其数据域大小重新插入到原来链表中 144 while (p != NULL) { 145 s = p; 146 p = p->next; 147 Node *q = list->first; 148 while (q->next != NULL && q->next->data < s->data) 149 q = q->next; 150 if (q->next == NULL)//判断q此时指向的是否是单链表的最后一个结点,若是则更新链表的尾指针 151 list->last = s; 152 //将结点重新插入链表 153 s->next = q->next; 154 q->next = s; 155 } 156 } 157 158 void reverse(List *list) { 159 //step 1:判断单链表中的结点数是否为0或1 160 if (list->size == 0 || list->size == 1) return; 161 //step 2:将单链表中第一个结点之后的链表部分截出,然后将截出的链表中的结点按头插法重新插入到原链表中 162 Node *p = list->first->next; 163 Node *q = p->next; 164 list->last = p; 165 list->last->next = NULL; 166 167 while (q != NULL) { 168 p = q; 169 q = q->next; 170 p->next = list->first->next; 171 list->first->next = p; 172 } 173 } 174 175 void clear(List *list) { 176 //step 1:判断单链表是否为空 177 if (list->size == 0) return; 178 //step 2:释放单链表中的每一个结点 179 Node *p = list->first->next; 180 while (p != NULL) { 181 list->first->next = p->next; 182 free(p); 183 p = list->first->next; 184 } 185 //step 3:头指针和尾指针重新都指向头结点 186 list->last = list->first; 187 //step 4:更新链表长度 188 list->size = 0; 189 } 190 191 void destroy(List *list) { 192 //step 1:清空单链表 193 clear(list); 194 //step 2:释放头结点 195 free(list->first); 196 //step 3:头指针和尾指针都赋值为空 197 list->first = list->last = NULL; 198 }
main.cpp
1 #include"slist.h" 2 3 void main() { 4 List mylist; 5 InitList(&mylist); 6 7 ElemType item; 8 Node *p = NULL; 9 int select = 1; 10 while (select) { 11 printf("******************************************* "); 12 printf("*[1] push_back [2] push_front * "); 13 printf("*[3] show_list [4] pop_back * "); 14 printf("*[5] pop_front [6] insert_val * "); 15 printf("*[7] find [8] length * "); 16 printf("*[9] delete_val [10] sort * "); 17 printf("*[11] reverse [12] clear * "); 18 printf("*[13*] destroy [0] quit_system * "); 19 printf("******************************************* "); 20 printf("请选择:>>"); 21 scanf("%d", &select); 22 if (select == 0) break; 23 switch (select) { 24 case 1: 25 printf("请输入要插入的数据(-1结束):>"); 26 while (scanf("%d", &item), item != -1) { 27 push_back(&mylist, item); 28 } 29 break; 30 case 2: 31 printf("请输入要插入的数据(-1结束):>"); 32 while (scanf("%d", &item), item != -1) { 33 push_front(&mylist, item); 34 } 35 break; 36 case 3: 37 show_list(&mylist); 38 break; 39 case 4: 40 pop_back(&mylist); 41 break; 42 case 5: 43 pop_front(&mylist); 44 break; 45 case 6: 46 printf("请输入要插入的数据:>"); 47 scanf("%d", &item); 48 insert_val(&mylist, item); 49 break; 50 case 7: 51 printf("请输入要查找的数据:>"); 52 scanf("%d", &item); 53 p = find(&mylist, item); 54 if (p == NULL) 55 printf("要查找的数据在单链表中不存在! "); 56 break; 57 case 8: 58 printf("单链表的长度为%d ", length(&mylist)); 59 break; 60 case 9: 61 printf("请输入要删除的值:>"); 62 scanf("%d", &item); 63 delete_val(&mylist, item); 64 break; 65 case 10: 66 sort(&mylist); 67 break; 68 case 11: 69 reverse(&mylist); 70 break; 71 case 12: 72 clear(&mylist); 73 break; 74 //case 13: 75 //destroy(&mylist); 76 //break; 77 default: 78 printf("选择错误,请重新选择! "); 79 break; 80 } 81 } 82 destroy(&mylist); //程序结束,摧毁链表 83 }