循环链表
概念:表中最后一个节点的指针域指向头结点,整个链表形成一个环。
循环单链表 与 双向循环链表的操作(初始化、插入、删除、判断是否为空等):
//带头结点的循环单链表
typedef struct LNode{
ElemType data;
struct LNode *next;
}LNode,*Linklist;
bool Initlist(Linklist &L){
L=(LNode *)malloc(sizeof(LNode)); //分配一个头结点,且不存储任何数据
if(L==NULL)
return false; //内存不足,分配失败
L->next=L; //区别于单链表的初始化,头结点的next指向头结点
return ture;
}
//判断循环单或双链表是否为空
bool Empty(Linklist L){
return(L->next==L);
}
//判断结点p是否是循环单或双链表的表尾结点
bool isTail(Linklist L,LNode *p){
return(p->next==L);
}
//初始化循环双链表
bool InitDLinklist(DLinklist &L){
L=(DLNode *)malloc(sizeof(DLNode)); //分配一个头结点,且不存储任何数据
if(L==NULL)
return false; //内存不足,分配失败
L->prior=L; //区别于循环单链表的初始化,头结点的prior指向头结点
L->next=L;
return ture;
}
//循环双链表的插入
bool InsertNextDNode(DNode *p,DNode *s){
s->next=p->next;
p->next->prior=s;
s->prior=p;
p->next=s;
}
//循环双链表的删除
bool DeleteDNode(DNode *p){
p->next=q->next;
q->next->prior=p;
free(q);
}
双向链表
操作:判断链表是否为空、计算链表的长度、遍历链表,注重区别于单恋表的是插入 和 删除操作。
#include<iostream>
using namespace std;
//定义双向链表
typedef struct DuLNode
{
int data;
struct DuLNode *prior;
struct DuLNode *next;
}DuLNode, *DuLinkList;
// 初始化
int InitList(DuLinkList &L)
{
L = new DuLNode;
L->next = NULL;
L->prior = NULL;
return 1;
}
//判断链表是否为空
int ListEmpty(DuLinkList L)
{
if (L->next == NULL)
{
return 1; //空
}
else
{
return 0; //非空
}
}
//计算链表的长度
int ListLength(DuLinkList L)
{
int length = 0;
DuLNode *p;
p = L->next;
while (p)
{
p = p->next;
length++;
}
return length;
}
//遍历链表
void TraveList(DuLinkList L)
{
DuLNode *p;
p = L->next;
while (p)
{
printf("%d ", p->data);
p = p->next;
}
printf("\n");
}
//头插法创建单链表
void CreateList_F(DuLinkList &L, int n)
{
L = new DuLNode;
L->next = NULL;
L->prior = NULL;
printf("请输入链表的元素:\n");
for (int i = 0; i < n; i++)
{
printf("请输入第%d个元素的值:", i + 1);
DuLNode *s;
s = new DuLNode;
scanf("%d", &s->data);
s->next = L->next;
s->prior = L;
L->next = s;
}
}
//尾差法创建单链表
void CreateList_L(DuLinkList &L, int n)
{
L = new DuLNode;
L->next = NULL;
L->prior = NULL;
DuLNode *p;
p = L;
printf("请输入链表的元素:\n");
for (int i = 0; i < n; i++)
{
printf("请输入第%d个要元素的值:", i + 1);
DuLNode *s;
s = new DuLNode;
scanf("%d", &s->data);
s->prior = p;
s->next = NULL;
p->next = s;
p = s;
}
}
//双向链表的删除
int ListDelete(DuLinkList &L, int i, int &e)
{
//删除链表第i个位置上的元素,并用e返回其值,1<=i<=表长
DuLNode *p;
p = L;
int j = 0;
while (p->next&&j < i - 1)
{ //找到第i-1个结点
p = p->next;
j++;
}
if (!(p->next) || j > i - 1)
{
return 0;
}
DuLNode *q;
//q = new DuLNode;
q = p->next; //用q保存要删除的元素,以便释放
e = q->data;
p->next = q->next;//修改指针
q->next->prior = p;
delete q;
return 1;
}
//双向链表的插入
int ListInsert(DuLinkList &L, int i, int e)
{
//在双向链表的第i个位置之前插入元素e,1<=i<=表长+1
struct DuLNode *p;
p = L;
int j = 0;
while (p->next&&j < i - 1)
{
p = p->next;
j++;
}
if (!(p->next) || j > i - 1)
{
return 0;
}
DuLNode *s;//生成要插入的结点
s = new DuLNode;
s->data = e;
p->next->prior = s;
s->next = p->next;
p->next = s;
s->prior = p;
return 1;
}
int main()
{
DuLinkList L;
if (InitList(L))
{
printf("链表初始化成功!\n");
}
else
{
printf("链表初始化失败!\n");
}
if (ListEmpty(L))
{
printf("链表为空!\n");
}
else
{
printf("链表非空!\n");
}
printf("请输入链表的长度:");
int n;
scanf("%d", &n);
CreateList_L(L,n);
//CreateList_F(L, n);
printf("遍历链表:\n");
TraveList(L);
printf("请输入要删除元素的位置:");
int location1;
scanf("%d", &location1);
int e;
if (ListDelete(L, location1, e))
{
printf("删除成功!\n");
}
else
{
printf("删除失败!\n");
}
printf("要删除的元素的值是:%d\n", e);
printf("删除后链表结构:\n");
TraveList(L);
printf("删除后链表长度是:%d\n", ListLength(L));
printf("请输入要插入的位置和元素的值:\n");
int location2, value;
scanf("%d,%d", &location2, &value);
if (ListInsert(L, location2, value))
{
printf("插入成功!\n");
}
else
{
printf("插入失败!\n");
}
printf("插入后的链表:\n");
TraveList(L);
printf("插入后链表的长度是:%d\n", ListLength(L));
system("pause");
return 0;
}
参考:循环单双链表的操作