数据结构----循环单链表
一、定义
特点是表中最后一个节点的指针域指向头节点,整个链表形成一个单向环。由此,从表中任何一个节点出发均可找到表中其他节点。
循环链表的操作和线性链表的操作基本一致,差别仅在算法中的循环条件不是p或p->next是否为空,而是他们是否等于头指针
(a)非空表
(b)空表
二、代码实现
1、单循环链表结构体定义
根据上图,结构体定义如下:
(1)定义节点结构体
(2)定义链表结构体
typedef struct Node { ELemType data; struct Node *next; }Node, *PNode;//定义·节点 typedef struct List { PNode first; PNode last; int size; }List;//定义单循环链表
2、单循环链表的初始化
(1)头节点和尾节点分配同一空间
(2)尾节点的指针域指向头节点
(3)链表长度size置零
代码如下:
void InitSCList(List *list) { Node *s = (Node *)malloc(sizeof(Node)); assert(s!= NULL); list->first = list->last = s; list->last->next = list->first; list->size = 0; }
3、功能概述
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] quit_system *\n"); printf("***************************************************\n");
(1)编写申请节点函数
Node* _buynode(ELemType x) { Node *s = (Node*)malloc(sizeof(Node)); assert(s != NULL); s->data = x; s->next = NULL; return s; }
(2)编写尾插 [1] push_back 函数
void push_back(List *list, ELemType x) { Node *s = _buynode(x); list->last->next = s; list->last = s; list->last->next = list->first; list->size++; //insert(list, end(list), x); }
(3)编写遍历节点函数 [3] show_list函数
void show_list(List *list)
{
Node *p = list->first->next;
while (p !=list->first)//注意这里循环条件跟单链表循环条件不一样
{
printf("%d-->", p->data);
p = p->next;
}
printf("Null.\n");
}
(4)编写头插函数
void push_front(List *list, ELemType x) { //insert(list, begin(list), x); Node *s = _buynode(x); s->next = list->first->next; list->first->next = s; if (list->size == 0) { list->last = s; } list->size++; }
(5)剩余函数
#include "SCList.h" void InitSCList(List *list) { Node *s = (Node *)malloc(sizeof(Node)); assert(s!= NULL); list->first = list->last = s; list->last->next = list->first; list->size = 0; } void push_back(List *list, ELemType x) { Node *s = _buynode(x); list->last->next = s; list->last = s; s->next = list->first; list->size++; //insert(list, end(list), x); } /* void push_back(List *list, ElemType x) { //Node *s = _buynode(x); Node *s = (Node *)malloc(sizeof(Node)); assert(s!=NULL); s->data = x; s->next = NULL; list->last->next = s; list->last = s; list->size++; } */ void push_front(List *list, ELemType x) { //insert(list, begin(list), x); Node *s = _buynode(x); s->next = list->first->next; list->first->next = s; if (list->size == 0) { list->last = s; } list->size++; } /* void push_front(List *list, ElemType x) { //Node *s = _buynode(x); Node *s = (Node *)malloc(sizeof(Node)); assert(s != NULL); s->data = x; s->next =list->first->next; list->first->next = s; list->last = s; if (list->size == 0) { list->last = s; } list->size++; } */ void show_list(List *list) { Node *p = list->first->next; while (p !=list->first) { printf("%d-->", p->data); p = p->next; } printf("Null.\n"); } void pop_back(List *list) { if (list->size == 0) return; Node *p = list->first; while (p->next != list->last) { p = p->next; } free(list->last); list->last = p; list->last->next = list->first; list->size--; } void pop_front(List *list) { if (list->size == 0) return; Node *p = list->first->next; list->first->next = p->next; free(p); p = NULL; list->size--; if (list->size == 0) list->last = list->first; } void insert_val(List *list, ELemType x) { Node *s = _buynode(x); /*Node *s = (Node *)malloc(sizeof(Node)); s->data = x;*/ Node *p = list->first; while (p->next != list->first && p->next->data <= s->data) { p = p->next; } if (p->next == list->first) { list->last = s; } s->next = p->next; p->next = s; list->size++; } Node* find(List *list, ELemType key) { if (list->size == 0) return NULL; Node *p = list->first; while (p->next != list->first && p->next->data != key)//条件顺序不能颠倒 { p = p->next; } if (p->next == list->first) return NULL; return (p->next); } int length(List *list) { return list->size; } void delete_val(List *list, ELemType key) { if (list->size == 0) return; Node *p = find(list, key); if (p == NULL) { printf("要删除的数据不存在\n"); return; } if (p == list->last) { pop_back(list); } else if (p->next->next == NULL) { //将q节点复制给p节点,并删除q节点 若q节点是最后一个节点,则需要修改last指针 Node *q = p->next; p->data = q->data; p->next = q->next; free(q); q = NULL; list->size--; list->last = p; printf("%p", list->last); } else { //将q节点复制给p节点,并删除q节点 Node *q = p->next; p->data = q->data; p->next = q->next; free(q); q = NULL; list->size--; } } void sort(List *list) { if (list->size == 0 || list->size == 1) return; Node *s = list->first->next; Node *q = s->next; list->last = s; list->last->next = NULL; while (q != NULL) { s = q; q = q->next; Node *p = list->first; while (p->next != list->first && p->next->data <= s->data) p = p->next; if (p->next == list->first) { list->last = s; } s->next = p->next; p->next = s; } } void reverse(List *list) { if (list->size == 0 || list->size == 1) return; Node *p = list->first->next; Node *q = p->next; list->last->next = NULL; 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(List *list) { if (list->size == 0) return; Node *p = list->first->next; while (p != list->first) { list->first->next = p->next; free(p); p = list->first->next; } list->last = list->first; list->size = 0; } void destroy(List *list) { clear(list); free(list->first); list->first = list->last = NULL; } ///////////////////////////////////// Node* _buynode(ELemType x) { Node *s = (Node*)malloc(sizeof(Node)); assert(s != NULL); s->data = x; s->next = NULL; return s; } It begin(List *list) { return list->first->next; } It end(List *list) { return list->last->next;//(单链表是NULL) } void insert(List *list, It pos, ELemType x) { Node *p = list->first; while (p->next != pos) { p = p->next; } Node *s = _buynode(x); s->next = p->next; p->next = s; if (pos == NULL) list->last = s; list->size++; }