简介:

  在用C/C++开发系统中,我们知道用数组或者单链表来开发,如果是数据比较大的话,性能很不好,效率也不高。因此常常需要考虑系统的实用性,常常采用双向链表来开发。

示例:

1.数据

typedef struct node{

  int data;                // 数据

  struct node *last;  // 前一个数据节点 

  struct node *next;  // 后一个数据节点

}Node;

typedef struct {

  Node *head;

  Node *tail;

}LinkList;

2.创建链表

LinkList *createList()
{
LinkList *list = malloc(sizeof(LinkList));
list -> head = NULL;
lsit ->tail = NULL;
return list;
}

3.插入

  3.1头插法

void addNodeBeHead(LinkList *list,int num)
{
Node *p = malloc(sizeof(Node));
p -> data = num;
p -> last = NULL;
P -> next = NULL; if(list - > head != NULL)
{
// 1.指向新的节点
// 2.新节点的next指向原来的节点
// 3.新节点变成头节点
list ->head->last = p;
node ->next = list ->head;
list -> head = p;
}
else{
list -> head = P;
list -> tail = p;
}
}

  3.2尾插法

void addNodeAfterTail(LinkList *list,int num)
{
Node *p = malloc(sizeof(Node));
p -> data = num;
p -> last = NULL;
P -> next = NULL; if(list - > head != NULL)
{
// 1.指向新的节点
// 2.新节点的last指向原来的节点
// 3.新节点变成尾节点
list ->tail->next = p;
node ->last = list -> tail;
list -> tail = p;
}
else{
list -> head = P;
list -> tail = p;
}
}

4.打印链表

void printList(LinkList *list)
{
Node *p = list -> head;
if(p == NULL)
{
printf("当前为空链表");
}else
{
while(p != NULL)
{
printf("%s",p-> data);
p = p-> next;
} }
}

5.把链表的头结点删除,并返回头结点的数值

int popHeadNode(LinkList *list)
{
if(list -> head == NULL)
{
printf("the list is empty!");
return -;
}
else if (list -> head == list -> tail)
{
Node *node = list - > head;
int value = node ->data;
list -> head = NULL;
list -> tail = NULL;
free(node);
return value;
}
else
{
Node *node = list -> head;
int value = node -> data;
// 1.head指向下一个节点
// 2.并将下一个的last置空
list -> head = list -> head ->next;
list -> head -> last = NULL;
free(node);
return value; } }

6.统计节点总数

int countNodes(LinkList *list)
{
int count = ;
Node *p = list -> head;
if(list -> head != NULL)
{
while(p != NULL)
{
count++;
p = p -> next;
}
return count; }
return ;
}

7.链表转成数组(注意:数组一定要malloc初始化,否则无法返回)

int *listToArray(LinkList *list)
{
if(list -> head == NULL)
{
return NULL;
} int i = ;
int n = countNodes(list);
int *arr = malloc(sizeof(int) * n);
Node *p = list -> head;
while(p != NULL)
{
arr[i] = p -> data;
i++;
p = p -> next;
}
return arr;
}

8.把链表所有的节点头尾对调

1->2->3->NULL 对调后 NULL->3->2->1

void reverseList(LinkList *list)
{
if(list -> head != NULL)
{
int *arr = listToArray(list);
int i = countNodes(list) - ;
Node *node = list -> head;
while(p != NULL)
{
P -> data = arr[i];
i --;
p = p -> next;
}
}
}

第二种做法:(把原来的链表重新连接)

void reverseList(LinkList *list)
{ Node *prev = NULL;
Node *p = list -> head;
Node *temp;
list -> tail = p; // 尾部变头部
while(p != NULL)
{
temp = p -> next;
p -> next = prev;
prev = p;
p = temp;
}
list ->head = prev;
}

第三篇、C_双向链表(循环链表)的更多相关文章

  1. LWJGL3的内存管理,第三篇,剩下的两种策略

    LWJGL3的内存管理,第三篇,剩下的两种策略 上一篇讨论的基于 MemoryStack 类的栈上分配方式,是效率最高的,但是有些情况下无法使用.比如需要分配的内存较大,又或许生命周期较长.这时候就可 ...

  2. 从0开始搭建SQL Server AlwaysOn 第三篇(配置AlwaysOn)

    从0开始搭建SQL Server AlwaysOn 第三篇(配置AlwaysOn) 第一篇http://www.cnblogs.com/lyhabc/p/4678330.html第二篇http://w ...

  3. (转) 从0开始搭建SQL Server AlwaysOn 第三篇(配置AlwaysOn)

    原文地址: http://www.cnblogs.com/lyhabc/p/4682986.html 这一篇是从0开始搭建SQL Server AlwaysOn 的第三篇,这一篇才真正开始搭建Alwa ...

  4. 【第三篇】ASP.NET MVC快速入门之安全策略(MVC5+EF6)

    目录 [第一篇]ASP.NET MVC快速入门之数据库操作(MVC5+EF6) [第二篇]ASP.NET MVC快速入门之数据注解(MVC5+EF6) [第三篇]ASP.NET MVC快速入门之安全策 ...

  5. 第三篇 Entity Framework Plus 之 Query Cache

    离上一篇博客,快一周,工作太忙,只能利用休息日来写一些跟大家分享,Entity Framework Plus 组件系列文章,之前已经写过两篇 第一篇 Entity Framework Plus 之 A ...

  6. 我的屌丝giser成长记-研三篇

    进入研三以来,基本都是自己的自由时间了,从导师的项目抽离出来,慢慢的都交给师弟他们来负责.研三的核心任务就是找工作以及写毕业论文,因为有导师科研基金项目成果作为支撑,所以自己的论文没什么可担心,一切都 ...

  7. javascript面向对象系列第三篇——实现继承的3种形式

    × 目录 [1]原型继承 [2]伪类继承 [3]组合继承 前面的话 学习如何创建对象是理解面向对象编程的第一步,第二步是理解继承.本文是javascript面向对象系列第三篇——实现继承的3种形式 [ ...

  8. 前端工程师技能之photoshop巧用系列第三篇——切图篇

    × 目录 [1]切图信息 [2]切图步骤 [3]实战 前面的话 前端工程师除了使用photoshop进行测量之外,更重要的是要使用该软件进行切图.本文是photoshop巧用系列的第三篇——切图篇 切 ...

  9. 解剖SQLSERVER 第三篇 数据类型的实现(译)

    解剖SQLSERVER 第三篇  数据类型的实现(译) http://improve.dk/implementing-data-types-in-orcamdf/ 实现对SQLSERVER数据类型的解 ...

  10. 深入理解javascript函数系列第三篇——属性和方法

    × 目录 [1]属性 [2]方法 前面的话 函数是javascript中的特殊的对象,可以拥有属性和方法,就像普通的对象拥有属性和方法一样.甚至可以用Function()构造函数来创建新的函数对象.本 ...

随机推荐

  1. UITextView详解

    self.textView = [[[UITextView alloc] initWithFrame:self.view.frame] autorelease]; //初始化大小并自动释放   sel ...

  2. SQL提高查询效益之in、not in、between、like等条件讲述

    在使用SQL语句查询数据库记录时,如果要查询相同的内容,有着不同的多种方法. 仍然,尽管使用多种方法可以得到相同的结果,但是,如果您使用不同的方法,在执行效益上是截然不同的.因此,我们得仔细考虑,如果 ...

  3. JavaScript(十一) HTML DOM - 改变CSS

    HTML DOM 允许 JavaScript 改变 HTML 元素的样式. A.改变 HTML 样式 如需改变 HTML 元素的样式,请使用这个语法: document.getElementById( ...

  4. 文件控制列表命令setfacl和getfacl的使用

    一 需求 有以下需求,通过setfacl命令实现 一组用户可写可读可执行,一组用户可写可执行,另一组用户只可读 linux rwx oracle wx uplook r 二 解决 第一步 添加六个用户 ...

  5. cocos2d-x 屏幕坐标系和OPenGL坐标系转换

    转自:http://home.cnblogs.com/group/topic/57609.html cocos2d坐标系(OPenGL坐标系):以左下角为原点,x向右,y向上 屏幕坐标系(androi ...

  6. Android AndroidManifest 清单文件以及权限具体解释

    每一个Android应用都须要一个名为AndroidManifest.xml的程序清单文件,这个清单文件名称是固定的而且放在每一个Android应用的根文件夹下.它定义了该应用对于Android系统来 ...

  7. Nginx+Tomcat动静态资源分离

    1 创建用户.用户组 useradd -g users www passwd www //设置密码,否则该用户不可用 groupadd -g 888 www //创建用户组 gpasswd -a ww ...

  8. Supervised Learning-Regression

    假设我们有一张房子属性及其价格之间的关系表(如下图所示) ,根据这些数据如何估计其他房子的价格?我们的第一个反应肯定是参考属性相似的房子的价格.在属性较少时这个方法还行得通,属性太复杂时就不那么简单了 ...

  9. [置顶] 博客已迁移至ryantang.me

    大家好,感谢大家一直以来的支持,本博客内容已停止更新,新内容将发布到我的新博客,地址是:ryantang.me,欢迎大家继续支持,我会在ryantang.me上发布内容更丰富的文章内容,谢谢! Rya ...

  10. JQuery实现页面Loading效果

    第一步:添加遮罩层和LOADING层 <div class="overlay"></div><div id="AjaxLoading&quo ...