数据结构之双向链表

双向链表的实现【C语言】

概念:

双向链表还是单链表,其逻辑存储是连续的,但物理存储空间不连续

包含数据域、直接前驱域和直接后继域。

可以从前向后遍历,也可以从后向前遍历。

双链表的实现

  • 结构的声明:
typedef int elemType;

typedef struct Node
{
	union {
		int length;
		elemType data;
	};

	struct Node *prior;
	struct Node *next;
}doublelist;

  • 方法的声明
//方法的声明
void InitDoubleList(doublelist* head);//初始化

bool InsertDoubleList(doublelist* head,int value,int pos);//按位置插入

bool InsertDoubleListHead(doublelist* head,int value);//头插

bool InsertDoubleListRear(doublelist* head,int value);//尾插

bool DeleteDoubleList(doublelist* head,int pos);//按位置删

bool DeleteDoubleListHead(doublelist *head);//头删

bool DeleteDoubleListRear(doublelist *head);//尾删

bool DeleteDoubleListFromVal(doublelist *head,int value);//按值删

bool IsEmpty(doublelist* head);//判空

int GetLength(doublelist* head);//长度

void DestoryDoubleList(doublelist* head);//销毁


  • 方法的实现
#include<stdio.h>
#include<stdlib.h>
#include"doublelist.h"

//申请新结点(只在本文件内使用)
static doublelist* ApplyNewNode(doublelist* pri,doublelist* nex,int value)
{
	doublelist *new_node = (doublelist *)malloc(sizeof(doublelist));
	if (new_node == NULL) return NULL;

	new_node->data = value;
	new_node->next = nex;
	new_node->prior =pri;

	return new_node;
}

void InitDoubleList(doublelist* head)  //初始化
{
	if(head==NULL) exit(0);

	head->next =NULL;
	head->length =0;

}

bool InsertDoubleList(doublelist* head,int value,int pos)  //按位置插入
{
	if(head==NULL) exit(0);

	if(pos<0 || pos >GetLength(head) )  return false;

	doublelist *p=head;
	while(pos)
	{
		p=p->next ;
		pos--;
	}

	doublelist *new_node=ApplyNewNode(p,p->next,value);
	if (new_node == NULL) return false;

	if(p->next == NULL) //尾插
	{
		p->next =new_node;
	}
	else 
	{
		p->next->prior =new_node;
		p->next =new_node;
	}

	head->length ++;
	return true;
}

bool InsertDoubleListHead(doublelist* head,int value)  //头插
{
	if(head==NULL) exit(0);

	return InsertDoubleList(head,value,0);
}

bool InsertDoubleListRear(doublelist* head,int value)  //尾插
{
	if(head==NULL) exit(0);

	return InsertDoubleList(head,value,GetLength(head));
}

bool DeleteDoubleList(doublelist* head,int pos)  //按位置删
{
	if(head == NULL) exit(0);

	if (pos < 0 || pos >= GetLength(head)) return false;

	doublelist *p = head;

	while (pos)
	{
		p = p->next;
		pos--;
	}

	doublelist *q = p->next;
	if(q->next  != NULL) //删除尾结点
	{
		q->next->prior =p;
	}
	p->next = q->next;

	free(q);
	head->length--;
	return true;
}

bool DeleteDoubleListHead(doublelist *head)  //头删
{
	if(head==NULL) exit(0);

	return DeleteDoubleList(head,0);
}

bool DeleteDoubleListRear(doublelist *head) //尾删
{
	if(head== NULL) exit(0);

	return DeleteDoubleList(head,GetLength(head) -1);
}

bool DeleteDoubleListFromVal(doublelist *head,int value) //按值删
{
	if (head == NULL)  exit(0);

	doublelist *p = head;
	doublelist *q = head->next;

	while (q != NULL)
	{
		if (q->data == value)
		{
			if(q->next ==NULL) //删除尾结点
			{
				p->next = q->next;
			}
			else
			{
				p->next = q->next;
				q->next->prior =p;
			}
			free(q);
			q = p->next;
			head->length--;
		}
		else
		{
			p = q;
			q = q->next;
		}
	}

	return true;
}

bool IsEmpty(doublelist* head) //判空
{
	if (head == NULL)  exit(0);

	return head->length == 0;
}

int GetLength(doublelist* head)  //长度
{
	if(head==NULL) exit(0);

	return head->length ;
}

void DestoryDoubleList(doublelist* head)  //销毁
{
	if (head == NULL) exit(0);

	while (!IsEmpty(head))
	{
		DeleteDoubleListHead(head);
	}
}

void Show(doublelist *head)
{
	if(head==NULL) exit(0);

	doublelist *p=head->next ;
	printf("正向打印:\n");
	while(p->next !=NULL)
	{
		printf("%d ",p->data );
		p=p->next ;
	}
	printf("%d\n",p->data );

	printf("逆向打印:\n");
	while(p!=head)
	{
		printf("%d ",p->data );
		p=p->prior ;
	}
	printf("\n");
}

int main()
{
	doublelist head;
	InitDoubleList(&head);

	for(int i=1;i<6;i++)
	{
		InsertDoubleListHead(&head,i);
	}

	Show(&head);
	printf("单链表长度:%d\n",GetLength(&head));

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值