数据结构——循环链表与双链表

循环链表

概念:表中最后一个节点的指针域指向头结点,整个链表形成一个环。

循环单链表双向循环链表的操作(初始化、插入、删除、判断是否为空等):

//带头结点的循环单链表
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;
}

在这里插入图片描述

参考:循环单双链表的操作

数据结构—双向链表的基本操作

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值