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、排序和逆置代码画图演示