前言
所谓单循环链表,实际上就是在单链表的基础上,使最后一个结点的next指针再指向头结点,形成循环的效果。这样,从表中任何一个结点出发都可以找到其他结点的位置。
尾指针
顾名思义,尾指针是指向链表的最后一个结点。在单循环链表中,设立尾指针能使得一些操作简化,例如两个单循环链表的合并。
注
我们之前所写的管理结构,是既包括头指针又包括尾指针的,因此在实现某些操作时就很方便了。
单循环链表和单链表的实现思路、注意事项都是一样的,只是需要额外注意的是,在我们的管理结构中要注意保持last的next指针始终指向头结点,达到循环的效果。
附:单链表的实现思路及注意事项
数据结构(2.1)线性表之单链表的表示和实现
数据结构(2.2)线性表之单链表的具体实现
- 链表为空
- 链表非空
全部代码
单循环链表的各项操作与单链表并无差别,只是在判断链表结束的条件有差别,之前是判断next指针是否为空,现在需要判断是否为头结点。因此实现代码并没有巨大的改变,只是在一些判断条件上做出改变。
SCList.h
#ifndef SCList_h
#define SCList_h
#include <stdio.h>
#include <malloc.h>
#include <assert.h>
#define ElemType int
//结点的结构
typedef struct Node{
ElemType data;
struct Node *next;
}Node, *Pnode;
//链表的结构
typedef struct List{
Pnode first;
Pnode last;
int size;
}List;
//初始化单循环链表
void InitSCList(List *list);
//1.尾部插入
void push_back(List *list,ElemType x);
//2.头部插入
void push_fount(List *list,ElemType x);
//3.展示
void show_list(List *list);
//4.尾部删除
void pop_back(List *list);
//5.头部删除
void pop_fount(List *list);
//6.按值插入(要求插入前的链表是有序的(此处为顺序
void insert_val(List *list,ElemType x);
//7.按值查找
Node* find(List *list,ElemType x);
//8.获取长度
int length(List *list);
//9.按值删除
void delete_val(List *list,ElemType x);
//10.排序
void sort(List *list);
//11.逆置(前后转换
void resver(List *list);
//12.清除单链表 ->只清除数据,保留头结点
void clearList(List *list);
//13.摧毁 ->包括头结点在内一起摧毁
void destroy(List *list);
//生成一个结点
Node* getNode(ElemType x);
#endif /* SCList_h */
SCList.cpp
#include "SCList.h"
//初始化单循环链表
void InitSCList(List *list){
Node *s = (Node *)malloc(sizeof(Node));
assert(s != NULL);
list->first = list->last = s;
//让最后一个结点的next指向头部,形成循环
list->last->next = list->first;
list->size = 0;
}
//1.尾部插入
void push_back(List *list,ElemType x){
Node *s = getNode(x);
//将这个结点接到链表尾部
list->last->next = s;
//重新设置last指针的指向
list->last = s;
//让最后一个结点的next指向头部,形成循环
list->last->next = list->first;
list->size ++;
}
//2.头部插入
void push_fount(List *list,ElemType x){
Node