1、代码实现
#include<stdio.h> #include<malloc.h> #include<assert.h> typedef int ElemType; typedef struct Node{ ElemType data; struct Node* next; }Node,*PNode; typedef struct SCList{ PNode first; PNode last; int size; }SCList; void initSCList(SCList* list){ //申请空间 创建虚拟头节点 Node* node = (Node*)malloc(sizeof(Node)); assert(node != NULL); //第一个节点 和 最后一个节点 指向虚拟头节点 list->first = list->last = node; //虚拟头结点指向自己完成循环 node->next = node; //当前链表大小为0 list->size = 0; } //申请节点 Node* malloc_node(ElemType e){ Node* node = (Node* )malloc(sizeof(Node)); assert(node != NULL); node->next = NULL; node->data = e; return node; } //尾插 void push_back(SCList* list,ElemType e){ //申请新节点 Node* node = malloc_node(e); //链表最后一个节点指向新节点 list->last->next = node; //更新last指针 list->last = node; //新节点的next指向第一个节点 形成循环 node->next = list->first; //元素数量+1 list->size++; } //头插 void push_front(SCList* list,ElemType e){ //申请新节点 Node* node = malloc_node(e); node->next = list->first->next; list->first->next = node; //判断当前链表是否为空 if(list->first == list->last){ //为空当前插入的节点则为last所指向的节点 list->last = node; } list->size++; } //打印链表 void show_SCList(SCList* list){ Node* p = list->first->next; while(p != list->first){ printf("%d->",p->data); p = p->next; } printf("NULL .\n last=%d,size=%d",list->last->data,list->size); } //删除尾部 void pop_back(SCList* list){ if(list->size == 0){ //当前链表为空 printf("当前链表为空,不可删除.\n"); return; } PNode p = list->first; while(p->next != list->last){ p = p->next; } free(list->last); list->last = p; p->next = list->first; list->size--; } //删除头部 void pop_front(SCList* list){ if(list->size == 0){ //当前链表为空 printf("当前链表为空,不可删除.\n"); return; } Node* node = list->first->next; list->first->next = node->next; if(list->size == 1){ //说明删除的是最后一个元素 list->last = list->first; } free(node); list->size--; } //插入元素 [默认链表升序排序] void insert_val(SCList* list,ElemType e){ Node* node = malloc_node(e); Node* p = list->first; while(p->next != list->first && p->next->data < e){ p = p->next; } node->next = p->next; p->next = node; if(node->next == list->first){ //说明插入的位置是末尾 list->last = node; } list->size++; } //查找元素 Node* find(SCList* list,ElemType key){ if(list->first == list->last){ return NULL; } Node* p = list->first->next; while(p != list->first){ if(p->data == key){ return p; } p = p->next; } return NULL; } //返回链表长度 int length(SCList list){ return list.size; } //按值删除 void delete_val(SCList* list,ElemType e){ if(list->size == 0){ return; } Node* p = find(list,e); if(p == NULL){ return; } if(p->next == list->last){ pop_back(list); }else{ p->data = p->next->data; p->next = p->next->next; free(p); list->size--; } } //排序 void sort(SCList* list){ if(list->size <= 1){ return; } //指向第一个节点 Node* p = list->first->next; //指向第二个节点 Node* q = p->next; //将原链表最后一个节点指向NULL list->last->next = NULL; //改变last指针指向第一个节点 list->last = p; //形成循环 p->next = list->first; while(q != NULL){ p = q; q = q->next; Node* s = list->first; //找到要插入的位置的上一个节点 while(s->next != list->first && s->next->data < p->data){ s = s->next; } //插入该节点 p->next = s->next; s->next = p; if(s->next == list->first){ //插入的位置是末尾 list->last = p; } } } //逆置链表 void reverse(SCList* list){ if(list->size <= 1){ return; } //指向第一个节点 Node* p = list->first->next; //指向第二个节点 Node* q = p->next; //将原链表最后一个节点指向NULL list->last->next = NULL; //改变last指针指向第一个节点 list->last = p; //形成循环 list->last->next = list->first; while(q != NULL){ p = q; q = q->next; //头插法插入节点 p->next = list->first->next; list->first->next = p; } } //清空链表 void clear(SCList* list){ Node* p = list->first->next; while(p != list->first){ list->first->next = p->next; free(p); p = list->first->next; } list->last = list->first->next = list->first; list->size = 0; } //销毁链表 void destroy(SCList* list){ clear(list); free(list->first); list->first = list->last = NULL; } int main(){ SCList list; initSCList(&list); int select = 1; ElemType item = 0; while(select){ printf("\n"); printf("***********************************\n"); printf("* [1] push_back [2] push_front *\n"); printf("* [3] show_list [4] pop_back *\n"); printf("* [5] pop_front [6] insert_val *\n"); printf("* [7] find [8] length *\n"); printf("* [9] delete_val [10] sort *\n"); printf("* [11] reverse [12] clear *\n"); printf("* [13] destroy [0] exit_system *\n"); printf("***********************************\n"); printf("请选择> "); scanf("%d",&select); if(!select){ break; } PNode p = NULL; switch(select){ case 1: printf("请输入要输入的数据(-1结束):>"); while(scanf("%d",&item),item != -1){ push_back(&list,item); } break; case 2: printf("请输入要输入的数据(-1结束):>"); while(scanf("%d",&item),item != -1){ push_front(&list,item); } break; case 3: show_SCList(&list); break; case 4: pop_back(&list); break; case 5: pop_front(&list); break; case 6: printf("请输入要插入的数据:>"); scanf("%d",&item); insert_val(&list,item); break; case 7: printf("请输入要查找的数据:>"); scanf("%d",&item); p = find(&list,item); if(p == NULL){ printf("查找的数据不存在.\n"); } break; case 8: printf("该链表长度为: %d.\n",length(list)); break; case 9: printf("请输入要删除的数据:>"); scanf("%d",&item); delete_val(&list,item); break; case 10: sort(&list); break; case 11: reverse(&list); break; case 12: clear(&list); break; case 13: destroy(&list); break; } } destroy(&list); return 0; }
2、排序和逆置代码画图演示
标签:node,Node,单链,last,list,next,循环,first From: https://www.cnblogs.com/xpp3/p/18413303