双向链表的实现

双向链表的实现

双向链表:(头结点前驱指向NULL,尾结点后继指向NULL)
双向链表的设计

typedef int ELEMTYPE;

typedef struct DNode
{
	ELEMTYPE data;//数据域
	DNode *next;//指向直接后继
	DNode *prior;//指向直接前驱
}DNode, *Dlist;//Dlist == DNode*

双向链表的操作:

//初始化
void Initlist(Dlist plist);

//头插
bool Insert_head(Dlist plist, ELEMTYPE val);

//尾插
bool Insert_tail(Dlist plist, ELEMTYPE val);

//按位置pos插入
bool Insert_pos(Dlist plist, int pos, ELEMTYPE val);

//判空
bool IsEmpty(Dlist plist);

//获取链表有效节点个数
int GetLength(Dlist plist);

//查找第一个值是key的节点,找到的话返回这个节点,没找到的话返回NULL
DNode *Search(Dlist plist, ELEMTYPE key);

//删除位置pos
bool Delpos(Dlist plist, int pos);

//删除第一个值为key的节点
bool Delval(Dlist plist, ELEMTYPE key);

//尾删
bool Del_tail(Dlist plist);

//头删
bool Del_head(Dlist plist);

//找节点的前驱
DNode *Getprior(Dlist plist, ELEMTYPE val);

//找节点的后继
DNode *Getnext(Dlist plist, ELEMTYPE val);

//清空, 直接调用销毁
void Clear(Dlist plist);

//销毁
void Destroy(Dlist plist);

//打印
void Show(Dlist plist);

具体实现:

#include <stdio.h>
#include <assert.h>
#include <stdlib.h>// #include <malloc.h>
#include "dlist.h"

//初始化
void Initlist(Dlist plist)
{
	//断言
	assert(plist != NULL);//nullptr
	if(plist == NULL)
		return;

	//赋值为我们给的初始值
	//plist->data; 数据域不需要赋值
	plist->next = NULL;
	plist->prior = NULL;
}

static DNode *BuyNode(ELEMTYPE val)
{
	DNode *pnewnode = (DNode*)malloc(sizeof(DNode));
	if(pnewnode == NULL)
			return nullptr;
	pnewnode->data = val;
	pnewnode->next = NULL;
	pnewnode->prior = NULL;

	return pnewnode;
}
//头插
bool Insert_head(Dlist plist, ELEMTYPE val)
{
	//断言

	//创建一个新节点
	//DNode * pnewnode = BuyNode(val);
	DNode *pnewnode = (DNode*)malloc(sizeof(DNode));
	if(pnewnode == NULL)
			return false;
	pnewnode->data = val;
	pnewnode->next = NULL;
	pnewnode->prior = NULL;

	//插入
	pnewnode->next = plist->next;//永远第一步  先让新节点把下一个节点绑住  //结点
	pnewnode->prior = plist;

	//特殊:两种情况  一种有节点存在, 一个光杆司令
	if(plist->next != NULL)
	{
		plist->next->prior = pnewnode;// -> = (*).
	}
	
	plist->next = pnewnode;
	return true;
}

//尾插
bool Insert_tail(Dlist plist, ELEMTYPE val)
{
	//assert
	//创建新节点
	DNode *pnewnode = (DNode*)malloc(sizeof(DNode));
	pnewnode->data = val;

	//找到前驱

	DNode *p;
	for(p=plist; p->next!=NULL; p=p->next);

	//插入

	pnewnode->next = NULL;
	pnewnode->prior = p;

	p->next = pnewnode;
	return true;
}


//按位置pos插入
bool Insert_pos(Dlist plist, int pos, ELEMTYPE val)
{
	//断言
	assert(plist != NULL && pos>=0 && pos<=GetLength(plist));
	if(plist == NULL || pos<0 || pos>GetLength(plist))
		return false;

	//创建新节点
	DNode *pnewnode = (DNode*)malloc(sizeof(DNode));
	pnewnode->data = val;
	//找到插入的位置pos
	DNode *p = plist;
	for(int i=0; i<pos; i++)
	{
		p = p->next;
	}
	//for(p=plist,int i=0; i<pos; i++,p=p->next);
	//插入
	pnewnode->next = p->next;
	pnewnode->prior = p;
	if(p->next != NULL)
	{
		p->next->prior = pnewnode;
	}
	p->next = pnewnode;
	return true;
}

//判空
bool IsEmpty(Dlist plist)
{
	return plist->next == NULL;
}

//获取链表有效节点个数
int GetLength(Dlist plist)
{
	int count = 0;
	for(DNode *p=plist->next; p!=NULL; p=p->next)
	{
		count++;
	}

	return count;
}

//查找第一个值是key的节点,找到的话返回这个节点,没找到的话返回NULL
DNode *Search(Dlist plist, ELEMTYPE key)
{
	//assert
	//遍历找值为key的第一个节点

	for(DNode *p=plist->next; p!=NULL; p=p->next)
	{
		if(p->data == key)
		{
			return p;
		}
	}

	return NULL;
}

//删除位置pos
bool Delpos(Dlist plist, int pos)
{
	//assert
	assert(plist != NULL && pos>=0 && pos<GetLength(plist));
	if(plist == NULL || pos<0 || pos>=GetLength(plist))
		return false;
	//找到删除的位置
	DNode *p = plist;
	for(int i=0; i<=pos; i++)
	{
		p=p->next;
	}
	//删除节点
	p->prior->next = p->next;
	if(p->next != NULL)
	{
		p->next->prior = p->prior;
	}
	//释放空间
	free(p);
	p = NULL;

	return true;
}

//删除第一个值为key的节点
bool Delval(Dlist plist, ELEMTYPE key)
{
	//断言
	if(plist == NULL)
		return false;

	//找到位置pos的节点
	DNode *p = Search(plist,key);
	if(p == NULL)
	{
		return false;
	}

	//删除
	p->prior->next = p->next;
	if(p->next != NULL)
	{
		p->next->prior = p->prior;
	}
	
	//释放空间
	free(p);
	p = NULL;
	return true;
}


//尾删
bool Del_tail(Dlist plist)
{
	//断言
	if(plist == NULL)
		return false;
	//找删除的节点
	DNode *p;
	for(p=plist; p->next!=NULL; p=p->next);

	//删除
	p->prior->next = NULL;

	//释放内存
	free(p);
	p = NULL;
	return true;
}

//头删
bool Del_head(Dlist plist)
{
	//assert
	if(plist == NULL || plist->next == NULL)
		return false;

	//找到位置
	DNode *p = plist->next;
	
	//删除
	plist->next = p->next;
	if(p->next !=NULL)
	{
		p->next->prior = plist;
	}

	//释放内存
	free(p);
	p = NULL;

	return true;

}

//找节点的前驱
DNode *Getprior(Dlist plist, ELEMTYPE val)
{
	//assert
	DNode *p = Search(plist, val);
	/*if(p == NULL)
	{
		return NULL;
	}
	return p->prior;*/
	return p==NULL?NULL:p->prior;
	
}

//找节点的后继
DNode *Getnext(Dlist plist, ELEMTYPE val)
{
	DNode *p = Search(plist, val);
	return p==NULL?NULL:p->next;
}

//清空, 直接调用销毁
void Clear(Dlist plist)
{
	Destroy(plist);
}

//销毁
void Destroy(Dlist plist)
{
	//assert
	if(plist == NULL ||plist->next == NULL)
		return;
	DNode *p = plist->next;

	while(plist->next != NULL)
	{
		p = plist->next;
		plist->next = p->next; 
		free(p);
	}
}

//void Destroy1(Dlist plist)
//{
//	if(plist == NULL ||plist->next == NULL)
//		return;
//	DNode *p = plist->next;
//	DNode *q;
//	while(p != NULL)
//	{
//		q = p->next;
//		free(p);
//		p = q;
//	}
//
//	plist->next = NULL;
//}

//打印
void Show(Dlist plist)
{
	for(DNode *p=plist->next; p!=NULL; p=p->next)
	{
		printf("%d ", p->data);
	}
	printf("\n");
}

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值