数据结构基础06(双向循环链表)

一、双向循环链表

0.头文件

#pragma once

typedef int ElemType;
typedef struct Node
{
	ElemType data;
	struct Node* prior;
	struct Node* next;
}CDLNode,*CDLinkList;

void InitCDLinkList(CDLinkList list);

int InsertCDLinkListPos(CDLinkList list, ElemType val, int pos);
int InsertCDLinkListHead(CDLinkList list, ElemType val);
int InsertCDLinkListTail(CDLinkList list, ElemType val);

void ShowCDLinkList(CDLinkList list);
void RShowCDLinkList(CDLinkList list);


int DeleteCDLinkListPos(CDLinkList list, int pos);
int DeleteCDLinkListHead(CDLinkList list);
int DeleteCDLinkListTail(CDLinkList list);

1. 判空

#include<stdio.h>
#include<stdlib.h>
#include<assert.h>
#include"cdlist.h"

void DeterPointIsNull(CDLinkList list)
{
	assert(list != NULL);
	if (list == NULL)
	{
		exit(0);
	}
}

2. 申请新结点

static CDLinkList ApplyNode(ElemType val, CDLinkList prior, CDLinkList next)
{
	CDLinkList p = (CDLinkList)malloc(sizeof(CDLNode));
	assert(p != NULL);
	p->data = val;
	p->prior = prior;
	p->next = next;
	return p;
}

3. 初始化

void InitCDLinkList(CDLinkList list)
{
	DeterPointIsNull(list);
	list->prior = list->next=list;
}

4.获取长度

int GetLen(CDLinkList list)
{
	DeterPointIsNull(list);
	int len = 0;
	CDLinkList p = list->next;
	while (p != list)  //现在是循环链表  条件是p不等于头结点
	{
		len++;
		p = p->next;
	}
	return len;
}

5.插入

1.按位置插

//可以考虑pos和长度一半比较   考虑从前往后跑还是从后往前跑
int InsertCDLinkListPos(CDLinkList list, ElemType val, int pos)
{
	DeterPointIsNull(list);
	if (pos<0 || pos>GetLen(list))
	{
		printf("Pos is error,Insert Fail\n");
		return 0;
	}
	CDLinkList p = list;
	while (pos > 0)
	{
		p = p->next;
		pos--;
	}
	p->next->prior = ApplyNode(val, p, p->next);
	p->next= ApplyNode(val,p,p->next);
	return 1;
}

2.头插

//O(1)
int InsertCDLinkListHead(CDLinkList list, ElemType val)
{
	DeterPointIsNull(list);
	return InsertCDLinkListPos(list,val, 0);
}

3.尾插

//O(1)
int InsertCDLinkListTail(CDLinkList list, ElemType val)
{
	DeterPointIsNull(list);
	
	//return InsertCDLinkListPos(list, val,GetLen(list));
	//如果进行转调,反而会降低效率,提高时间复杂度,因为需要从头找到尾

	CDLinkList p = list->prior;//p就是最后一个节点
	p->next->prior = ApplyNode(val, p, p->next);
	p->next = ApplyNode(val, p, p->next);
	return 1;
}

6.打印

1.正向打印

void ShowCDLinkList(CDLinkList list)
{
	DeterPointIsNull(list);
	CDLinkList p = list->next;
	while (p != list)
	{
		printf("%d ", p->data);
		p = p->next;
	}
	printf("\n");
}

2.逆向打印

void RShowCDLinkList(CDLinkList list)
{
	DeterPointIsNull(list);
	CDLinkList p = list->prior;
	while (p != list)
	{
		printf("%d ", p->data);
		p = p->prior;
	}
	printf("\n");
}

7.删除

1.按位置删除

int DeleteCDLinkListPos(CDLinkList list, int pos)
{
	DeterPointIsNull(list);
	if (pos < 0 || pos >= GetLen(list))
	{
		printf("Pos is error,Delete Fail\n");
		return 0;
	}
	CDLinkList p = list;
	while (pos > 0)
	{
		p = p->next;
		pos--;
	}
	CDLinkList s = p->next;
	p->next = s->next;
	s->next->prior = p;
	free(s);
	return 1;
}

2.头删

int DeleteCDLinkListHead(CDLinkList list)
{
	DeterPointIsNull(list);
	return DeleteCDLinkListPos(list, 0);
}

3.尾删

int DeleteCDLinkListTail(CDLinkList list)
{
	DeterPointIsNull(list);
	CDLinkList p = list->prior;
	list->prior = p->prior;
	p->prior->next = list;

	free(p);
	return 1;
}

8.主函数

#include<stdio.h>
#include<stdlib.h>
#include<assert.h>
#include"cdlist.h"

int main()
{

	return 0;
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值