双向链表基本操作及代码优化技巧

本文介绍了双向链表的四种插入情况,并分享了代码优化技巧,包括避免冗余赋值和提炼相同功能的表达式。通过应用这些技巧,优化了双向链表的插入、删除和查找函数。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

以下是本人对双向链表的相关操作及相应的代码优化学习笔记

双向链表的插入有4种情况:

1插入到链表的开始位置

1插入到链表的中间位置

1插入到链表的结束位置

1链表为空,既插入到开始位置 同时也插入到结束位置。

1.5 以下是双向链表的示意图:


根据分析,写出代码如下:

代码 

#include<stdio.h>
#include<stdlib.h>
typedef struct node {

	struct node *prev;
	struct node *next;
	int 		value;


}Node;

Node *create_node(int value)
{
	
	Node *root =(Node *)malloc(sizeof(Node));
	if (root == NULL)
		return 0;
	root->next = NULL;
	root->prev = NULL;
	root->value = value;
	return root;
}
//此链表有头结点,头结点的prev next 指针分别
//指向第一个结点和最后一个结点
int list_insert1(Node *root,int value)
{
	Node *this;
	Node *that;
	Node *new;
	for (this = root;(that = this->next)!=NULL;
		this = that) {
		if (that->value == value){
			return 1;
		} 
		if (that->value > value) {
			break;
		}
	}
	//跳出for循环的条件是找到了待插入的结点
	//或则是一直没有找到,知道遍历到链表末尾
	//最后把新节点插入尾端
	new = create_node(value);
	//插入到链表开始位置,或则插入在链表中间
	if (that != NULL) {

		//插入起始位置
		if (this ==root) {
			new->next = that;
			root->next = new;
			new->prev = NULL;
			that->prev = new;			

		} else {
			new->next = that;
			this->next =new;
			new->prev = this;
			that->prev =new;
		}
	
	} else { 
		//在链表末尾,  that指针为NULL 时 跳出for循环
		if (this != root) { 
			this->next = new;
			new->next =	NULL;
			new->prev = this;
			root->prev = new;

		} else {  //链表为空
			root->next = new;
			new->next =	NULL;
			root->prev = new;
			new->prev = NULL;
		}	

	}
	
	return 0;

}

2上面这段代码过于冗长,此处介绍两个优化代码的技巧。

2.1 下面这种情况:

例子 2.1

if (x==3) {

y = 2;

something;//表示执行任意代码

j = 3;

}else {

  y = 2;

different something;

  j = 3;

}

向上面这段代码,因为x是否等于3,都会y始终等于j始终等于3。 y不会影响到x的测试结果。所以上面的代码可以提炼为下面的代码。

例子 2.2

y = 2;

if (x==3) {

something;

}else {

 different something;

}

j = 3;

如果if内的代码影响了x的测试结果,则不能把相同的提取出来,例如:

例子 2.3

if (x==3) {

x = 5;

something;

}else {

x = 5;

different something;

}

这里把x = 5 提取出去就会影响if的测试结果。所以该代码不能再优化了。此技巧看似简单,关键的时候会发挥很大的作用,能简化的代码量。

2.2 把看似表现形式不同,但功能是一样的表达式提炼出来,例如:

例子 2.4

int * point;

int * p;

something ;//表示执行一段代码

if (point != NULL)

p = point;

else 

p = NULL;

向上面这段代码就可以直接简化为下面的代码:

例子 2.5 

int * point;

int * p;

something ;//表示执行一段代码

p = point;

为什么可以这样呢?在2.1代码中,当point不为NULL时,的值为point的一份拷贝.

pointNULL时,p的值也为NULL,也可以认为ppoint的一份拷贝。这和语句

p = point;的效果是一样的。

运用上面2个优化技巧,可以对双向链表的插入代码(代码 1)进行优化,用技巧1优化后的代码为:

例子 3.1 

int list_insert2(Node *root,int value)
{
	Node *this;
	Node *that;
	Node *new;
	for (this = root;(that = this->next)!=NULL;
		this = that) {
		if (that->value == value){
			return 1;
		} 
		if (that->value > value) {
			break;
		}
	}

	new = create_node(value);
	if (that != NULL) {

		//插入起始位置
		new->next = that;//从if中提取出来的
		that->prev = new;//	从if中提取出来的
		if (this ==root) {
			
			root->next = new;
			new->prev = NULL;
			
		} else {
			this->next =new;
			new->prev = this;
			
		}
	
	} else { 
		new->next =	NULL;//从if中提取出来的
		root->prev = new;//从if中提取出来的
		if (this != root) { 
			this->next = new;
			new->prev = this;
			

		} else {  //链表为空
			root->next = new;
			new->prev = NULL;
		}	

	}
	
	return 0;

}

3.2 用技巧2优化后的代码如下:

例子 3.2

//存在两个优化技巧,代码提炼 ,
//把看似功能表示不同,功能相同的代码提炼出来。
int list_insert3(Node *root,int value)
{
	Node *this;
	Node *that;
	Node *new;
	for (this = root;(that = this->next)!=NULL;
		this = that) {
		if (that->value == value){
			return 1;
		} 
		if (that->value > value) {
			break;
		}
	}
	new = create_node(value);
	//代码提炼之后还是只修改4个指针
	// this->next  new->next  that->prev new->prev
	new->next = that;
	if (this ==root) {
		root->next = new;
		new->prev = NULL;		
	} else {
		this->next =new;
		new->prev = this;		
	}
	if (that != NULL) {
		that->prev =new;
	
	} else { 
		root->prev = new;
	}
	
	return 0;

}

运用上面介绍的技巧,现给出双向链表的删除 查找函数(函数已经优化过)。

4.1 删除函数代码:

例子 4.1

int list_delate(Node *root,int value)
{
	Node *this ;
	Node *that;
	Node *old;
	for (this = root;(that = this ->next) != NULL;
		this = that) {

		if (that ->value == value) {
			break;
		}

	}
	if (that == NULL) {
		printf("waring:the value( %d) is not in the list!\n",value);
		return 1;

	}
	
	old = that;
	this ->next = that ->next;
	if (this == root) {
		
		that ->next->prev = NULL;

	} else {
	
		if (that ->next == NULL) {
			root ->prev =this;
		} else {
			that ->next->prev = this;	
		}

	}
	free(old);
	old == NULL;

	return 0;
	

}

4.2 查找函数代码:

例子 4.2 

Node *list_search(Node *root,int value)
{

	Node *this ;
	Node *that;
	Node *old;
	for (this = root;(that = this ->next) != NULL;
		this = that) {

		if (that ->value == value) {
			break;
		}

	}
	if (that == NULL) {
		printf("waring:the value( %d) is not in the list!\n",value);
		return NULL;

	}

	return that;

}
 5 下面是对上面函数的测试验证代码:

int main(int argc,char **argv)
{
	//创建头结点,头结点的prev next指针
	//作为链表的根指针 和尾指针
	Node *root = create_node(0);
	//随即插入不同的节点
	list_insert1(root, 3);
	list_insert1(root, 13);
	list_insert1(root, 23);
	list_insert1(root, 5);
	list_insert1(root, 6);
	list_insert1(root, 10);
	list_insert1(root, 12);
	list_insert1(root, 33);

	Node *current = root->prev;
	//按降序方式打印出来
	while (current !=NULL) {
		printf("root->next->value =%d\n",current->value);
		current = current->prev;
	}
	printf("=======================\n");
	list_delate(root,10);
	list_delate(root,33);
	list_delate(root,12);
	list_delate(root,12);
	current = root->prev;
	while (current !=NULL) {
		printf("root->next->value =%d\n",current->value);
		current = current->prev;
	}
	printf("=======================\n");
	Node * ret = list_search(root,3);
	printf("ret->value = %d\n",ret->value);
	return 0;
}

欢迎留言讨论,本文原创,转载请注明原出处。原文地址:http://blog.youkuaiyun.com/pengqian652/article/details/13629053













评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值