双向链表基本操作及代码优化技巧
2013-10-30 15:59
429 查看
以下是本人对双向链表的相关操作及相应的代码优化学习笔记
1 双向链表的插入有4种情况:
1.1 插入到链表的开始位置
1.2 插入到链表的中间位置
1.3 插入到链表的结束位置
1.4 链表为空,既插入到开始位置 同时也插入到结束位置。
1.5 以下是双向链表的示意图:
根据分析,写出代码如下:
代码 1 :
2上面这段代码过于冗长,此处介绍两个优化代码的技巧。
2.1 下面这种情况:
例子 2.1:
if (x==3) {
y = 2;
something;//表示执行任意代码
j = 3;
}else {
y = 2;
different something;
j = 3;
}
向上面这段代码,因为x是否等于3,都会y始终等于2 ,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时,p 的值为point的一份拷贝.
当point为NULL时,p的值也为NULL,也可以认为p是point的一份拷贝。这和语句
p = point;的效果是一样的。
3 运用上面2个优化技巧,可以对双向链表的插入代码(代码 1)进行优化,用技巧1优化后的代码为:
例子 3.1 :
3.2 用技巧2优化后的代码如下:
例子 3.2:
4 运用上面介绍的技巧,现给出双向链表的删除 查找函数(函数已经优化过)。
4.1 删除函数代码:
例子 4.1:
4.2 查找函数代码:
例子 4.2 :
5 下面是对上面函数的测试验证代码:
6 欢迎留言讨论,本文原创,转载请注明原出处。原文地址:/article/10098737.html
1 双向链表的插入有4种情况:
1.1 插入到链表的开始位置
1.2 插入到链表的中间位置
1.3 插入到链表的结束位置
1.4 链表为空,既插入到开始位置 同时也插入到结束位置。
1.5 以下是双向链表的示意图:
根据分析,写出代码如下:
代码 1 :
#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始终等于2 ,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时,p 的值为point的一份拷贝.
当point为NULL时,p的值也为NULL,也可以认为p是point的一份拷贝。这和语句
p = point;的效果是一样的。
3 运用上面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 运用上面介绍的技巧,现给出双向链表的删除 查找函数(函数已经优化过)。
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; }
6 欢迎留言讨论,本文原创,转载请注明原出处。原文地址:/article/10098737.html
相关文章推荐
- 【编程技巧】一些 NSArray 的基本操作代码例子
- 双向链表基本操作以及优化可能
- 快速排序基本操作的优化(完整代码)
- 数据库基本操作小摘(代码由mysql-essential-5.1.50-win32测试通过)
- Linux最基本的操作技巧
- C# j基本操作-拷贝文件夹的所有内容到另一个文件夹内: 复制代码 1 public static void CopyDir(string srcPath, string实现文件夹的复制以及删除
- Berkeley db 基本操作代码(基础)
- lua:部分常用操作的效率对比及代码优化建议(附测试代码)
- 提高PHP性能的实用方法+40个技巧优化您的PHP代码
- 前端页面卡顿?或是DOM操作惹的祸,需优化代码
- C/C++ -- 代码技巧及优化
- jQuery代码优化之基本事件
- Spring的JDBCTemplate的基本代码操作,这里没用c3p0连接池,用的自带连接池。
- 高质量Python代码编写的5个优化技巧
- Java 中StringBuffer与StringBuilder区别(转)及String类的一些基本操作代码
- Python 代码性能优化技巧
- Excel 表格的基本操作(精选 39 个技巧)
- Python 代码性能优化技巧
- php代码优化技巧
- C++语言数据结构 串的基本操作实例代码