数据结构之双向链表

双向链表

节点结构体

typedef int Data;
typedef struct _node
{
​ Data data ; //存储数据
​ struct _node *pre; // 指向上一个节点
​ struct _node *next; // 指向下一个节点
}Node;

内存结构图

在这里插入图片描述

C实现

.h文件

#ifndef  _LINKLIST_H_
#define  _LINKLIST_H_

typedef enum {TRUE,FALSE,ERROR} Bool;

typedef int Data;

typedef struct _node
{
	Data  data ;            //存储数据
	struct _node   *pre;    // 指向上一个节点	
	struct _node   *next;   // 指向下一个节点
}Node;

typedef struct _list
{
	Node *head;  //指向头结点;
}List;



//创建空链表
List* Creat ();

//摧毁链表
//[in]list  : 需要摧毁的链表
void destroy(List*list);


//插入数据:头插
// [in]list  : 要插入的双向链表
// [in]data  : 要插入的数据
Bool Insert_Head(List*list,Data data);

//插入数据:尾插
// [in]list  : 要插入的双向链表
// [in]data  : 要插入的数据
Bool Insert_Tail(List*list,Data data);

//插入数据:	按位置插入
// [in]list  : 要插入的双向链表
// [in]pos  : 要插入的位置
// [in]data  : 要插入的数据
Bool Insert_Pos(List*list,int pos,Data data);


//删除数据:	按位置删除
// [in]list  : 要插入的双向链表
// [in]pos  : 要插入的位置
Bool Delete_Pos(List*list,int pos);


//删除数据:	按数据删除
// [in]list  : 要插入的双向链表
// [in]data  : 要插入的数据
Bool Delete_Data(List*list,Data data);

//双向链表逆序
Bool Reverse(List *list);

//打印
void Display(List*list);

#endif  // _LINKLIST_H_

.c文件

#include <stdlib.h>
#include <stdio.h>
#include "linklist.h"

//创建空链表
List* Creat ()
{
	List *list = (List*)malloc(sizeof(List)/sizeof(char));
	if(NULL ==list)
	{
		return NULL ;
	}

	list->head = (Node*)malloc(sizeof(Node)/sizeof(char));
	if(NULL == list->head )
	{
		free(list);
		return NULL;
	}

	list->head->pre  = NULL;
	list->head->next = NULL;
	return list;
}

//摧毁链表
void destroy(List*list)
{
	if(list == NULL)
		return;

	Node *tmp = list->head->next; //指向第一个节点

	while(tmp != NULL)
	{
		Node *p   = tmp;
		tmp = tmp ->next;
		free(p);
	}

	free(list->head );
	free(list);

}

Bool Insert_Head(List*list,Data data)
{
	if(NULL == list)
		return ERROR;

	Node * new_node= (Node*)malloc(sizeof(Node)/sizeof(char));
	if(NULL == new_node)
	{
		return FALSE;
	}
	new_node ->data  = data;

	new_node ->next  = list->head->next;
	list->head->next = new_node;

	new_node->pre    = list->head;
	if(NULL != new_node ->next)
	{
		new_node ->next->pre = new_node;
	}
	

	return TRUE;
}

Bool Insert_Tail(List*list,Data data)
{
	if(NULL == list)
		return ERROR;

	Node * new_node= (Node*)malloc(sizeof(Node)/sizeof(char));
	if(NULL == new_node)
	{
		return FALSE;
	}

	new_node ->data = data;
	new_node ->next = NULL;

	//找到最后指向空的节点
	Node *tmp = list->head;  //指向头结点
	while(tmp->next)
	{
		tmp = tmp->next;
	}

	tmp->next      = new_node;
	new_node->next = NULL;
	new_node->pre  = tmp;

	return TRUE;
}

Bool Insert_Pos(List*list,int pos,Data data)
{

	if(NULL == list || pos <1)
		return ERROR;

	Node *node = (Node*)malloc(sizeof(Node)/sizeof(char));
	if(NULL == node)
	{
		return FALSE;
	}

	Node *tmp =list->head;  //指向头结点

	//找到指点位置的插入的前一个节点
	int i;
	for(i=0;i<pos-1;i++)
	{
		tmp = tmp->next;
		if(NULL == tmp)
		{
			printf("%d的位置已越界\n",pos);
			return ERROR;
		}
	}

	node->data = data;

	node->next       = tmp->next;
	tmp->next        = node;
	node->pre    = tmp;
	if(NULL != node ->next)
	{
		node ->next->pre = node;
	}

	return TRUE;
}

Bool Delete_Pos(List*list,int pos)
{
	if(NULL == list || pos<1)
		return ERROR;


	Node *tmp = list->head;//指向头结点


	int i;
	for(i=0;i<pos-1;i++)
	{
		tmp =tmp->next;
		if(NULL == tmp->next)
		{
			printf("%d的位置已经越界\n",pos);
			return ERROR;
		}
	}

	Node *pos_node = tmp->next;
	tmp->next      = pos_node->next;
	pos_node->pre  = tmp; 
	free(pos_node);

	return TRUE;
}

Bool Delete_Data(List*list,Data data)
{

	if(NULL == list )
		return ERROR;

	Node *tmp =list->head;

	while (tmp->next)
	{
		if (tmp->next->data == data)
		{
			Node *cur = tmp->next;
			tmp->next = cur->next;
			cur->pre  = tmp;

			free(cur);

			return TRUE;
		}
		tmp = tmp->next;
	}
	return FALSE;
}

Bool Reverse(List *list)
{

	// NULL == list || NULL == list->head || NULL == list->head->next  空链表
	// NULL == list->head->next->next   只有一个节点
	if(NULL == list || NULL == list->head || NULL == list->head->next|| NULL == list->head->next->next)
		return ERROR;

	Node *cur =list->head->next; 
	
	while(cur->next != NULL)
	{
		//交换 pre 和 next
		Node *tmp = cur->next;  
		cur->next = cur->pre;	
		cur->pre  = tmp;	

		//下一个节点
		cur = tmp;
	}
	//逆序后的最后一个节点指向NULL
	list->head->next->next = NULL;

		
	//头结点指向逆序后的第一个节点
	list->head->next       = cur;

	cur->next = cur->pre;
	cur->pre  = list->head;


	return TRUE;
}

void Display(List*list)
{
	//
	if(NULL == list)
		return ;

	Node *tmp = list->head->next;  //指向第一个节点
	while(tmp)
	{
		printf("%-4d",tmp->data);
		tmp = tmp->next;
	}
	printf("\n");
}

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值