数据结构复习3. 链表-双向链表(C语言实现)

双向链表

双向链表顾名思义,各个节点前后都相连。就像下图表示的那样。
在这里插入图片描述

尾插法

既然是链表,那么就存在两种元素的插入方式。一为头插法,二为尾插法。我们现在介绍一下尾插法如何实现。

  1. 假设当前链表中有一个元素。
    在这里插入图片描述
  2. 然后在元素1的后面插入新的节点。
    在这里插入图片描述
  3. 插入完毕
    在这里插入图片描述

头插法

双向链表的头插法与单链表的头插法是相似的。只不过增加了向前的指针罢了。

  1. 假设链表中已有一个元素
    在这里插入图片描述
  2. 生成新节点,并在head后方插入新节点
    在这里插入图片描述
  3. 插入完成.
    在这里插入图片描述

C语言代码

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

typedef struct node
{
	int data;
	struct node* next;
	struct node* pre;
}List;


void _list_init(List* head)
{
	if (head == NULL)
	{
		printf("head node is NULL\n");
		assert(0);
	}
	else
	{
		List* temp = head;
		temp->next = NULL;
		temp->pre = NULL;
		temp->data = -1;
	}
}


void _insert_element_one_by_one(List* head, int num)//头插法
{
	if (head == NULL)
	{
		printf("head node is NULL\n");
		assert(0);
	}
	else
	{
		List* temp = head;

		List* new_node = (List*)malloc(sizeof(List));

		new_node->data = num;
		new_node->next = temp->next;
		new_node->pre = temp;
		temp->next = new_node;
		if (new_node->next != NULL)
		{
			new_node->next->pre = new_node;
		}
	}
}

void _INSERT_ELEMENT_ONE_BY_ONE(List* head, int num)//尾插法
{
	if (head == NULL)
	{
		printf("head node is NULL\n");
		assert(0);
	}
	else
	{
		List* temp = head;//生成临时头节点
		while (temp->next != NULL)
		{
			temp = temp->next;
		}

		List* new_node = (List*)malloc(sizeof(List));

		new_node->data = num;
		new_node->next = NULL;
		new_node->pre = temp;
		temp->next = new_node;
	}
}


void print_list_R_order(List* head)//逆序
{
	if (head == NULL)
	{
		printf("head node is NULL\n");
		assert(0);
	}
	else
	{
		List* temp = head->next;

		while (temp->next!= NULL)
		{
			temp = temp->next;//找到最后一个节点
		}

		while (temp != head)
		{
			printf("%d ", temp->data);
			temp = temp->pre;
		}

		printf("\n");

	}
}

void print_list_order(List* head)//从左到右
{
	if (head == NULL)
	{
		printf("head node is NULL\n");
		assert(0);
	}
	else
	{
		List* temp = head->next;

		while (temp != NULL)
		{
			printf("%d ", temp->data);
			temp = temp->next;//找到最后一个节点
		}
		printf("\n");

	}
}

int delete_element(List* head, int num)
{
	if (head == NULL)
	{
		printf("List is NULL\n");
		assert(0);
	}
	else {
		List* slow = head;
		List* finder = head->next;//快指针
		while (finder != NULL)
		{
			if (finder->data == num)
			{
				slow->next = finder->next;
				finder->next = slow;
				free(finder);
				break;
			}
			slow = slow->next;
			finder = finder->next;
		}
	}
	return 0;//没找到指定元素
}


int insert_element_behind_some_element(List* head,int num,int ele)
{
	if (head == NULL)
	{
		printf("List is NULL\n");
		assert(0);
	}
	else {

		List* finder = head->next;//快指针
		while (finder != NULL)
		{
			if (finder->data == num)
			{
				List* new_node = (List*)malloc(sizeof(List));
				new_node->data = ele;
				
				new_node->next = finder->next;
				finder->next = new_node;
				new_node->pre = finder;
				new_node->next->pre = new_node;
				break;
			}

			finder = finder->next;
		}
	}
	return 0;//没找到指定元素
}

int get_list_length(List* head)
{
	List* temp = head->next;
	int count = 0;
	while (temp != NULL)
	{
		count++;
		temp = temp->next;
	}
	return count;
}



int main()
{
	List* l = (List*)malloc(sizeof(List));
	List* L = (List*)malloc(sizeof(List));

	_list_init(l);
	_list_init(L);

	for (int i = 0; i < 10; i++)
	{
		printf("%d ", i);
		_insert_element_one_by_one(l,i); //头插
		_INSERT_ELEMENT_ONE_BY_ONE(L, i);//尾插
	}
	printf("\n");

	printf("print list l :");
	print_list_order(l);
	printf("print list l Reverse:");
	print_list_R_order(l);
	printf("print list L :");
	print_list_order(L);
	printf("print list L Reverse:");
	print_list_R_order(L);

	printf("delete element 8 at list l\n");
	delete_element(l, 8);
	printf("print list l :");
	print_list_order(l);

	printf("delete element 8 at list L\n");
	delete_element(L, 8);
	printf("print list L :");
	print_list_order(L);

	printf("insert 3 behind 3 at l\n");
	insert_element_behind_some_element(l, 3, 3);
	printf("print list l :");
	print_list_order(l);

	printf("insert 3 behind 3 at L\n");
	insert_element_behind_some_element(L, 3, 3);
	printf("print list L :");
	print_list_order(L);

}

以上代码执行结果

在这里插入图片描述
稍后会有循环链表,链表栈,链表队列~

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值