05 双向链表

双向链表

  1 #include <stdio.h>
  2 #include <stdlib.h>
  3 #include <string.h>
  4
  5 // 数据结构
  6 typedef struct node
  7 {
  8     int data;
  9     struct node *prev;
 10     struct node *next;
 11 }doubleList;
 12
 13 doubleList *doubleList_init(void)
 14 {
 15     doubleList *list = (doubleList *)malloc(sizeof(doubleList));
 16
 17     if (list == NULL)
 18     {
 19         return NULL;
 20     }
 21
 22     list->prev = list;
 23     list->next = list;
 24
 25     return list;
 26 }
 27
 28 int doubleList_add_head(doubleList *list, int data)
 29 {
 30     if (list == NULL)
 31     {
 32         return -1;
 33     }
 34
 35     // 记录第一个节点
 36     struct node *tmp = list->next;
 37
 38     struct node *node = (struct node *)malloc(sizeof(struct node));
 39     if (node == NULL)
 40     {
 41         return -2;
 42     }
 43
 44     node->data = data;
 45     node->prev = list;
 46     node->next = tmp;
 47
 48     list->next = node;
 49     tmp->prev = node;
 50
 51     return 0;
 52 }
 53
 54 int doubleList_add_tail(doubleList *list, int data)
 55 {
 56     if (list == NULL)
 57     {
 58         return -1;
 59     }
 60
 61     // 记录最后一个节点
 62     struct node *tmp = list->prev;
 63
 64     struct node *node = (struct node *)malloc(sizeof(struct node));
 65     if (node == NULL)
 66     {
 67         return -2;
 68     }
 69
 70     node->data = data;
 71     node->prev = tmp;
 72     node->next = list;
 73
 74     list->prev = node;
 75     tmp->next = node;
 76
 77     return 0;
 78 }
 79
 80 int doubleList_del_head(doubleList *list, doubleList **node)
 81 {
 82     if (list == NULL || list->next == list)
 83     {
 84         return -1;
 85     }
 86
 87     *node = list->next;
 88
 89     // 记录第二个节点
 90     doubleList *tmp = list->next->next;
 91
 92     list->next = tmp;
 93     tmp->prev = list;
 94
 95     return 0;
 96 }
 97
 98 int doubleList_del_tail(doubleList *list, doubleList **node)
 99 {
100     if (list == NULL || list->next == list)
101     {
102         return -1;
103     }
104
105     *node = list->prev;
106
107     // 记录倒数第二个节点
108     doubleList *tmp = list->prev->prev;
109
110     list->prev = tmp;
111     tmp->next = list;
112
113     return 0;
114 }
115
116 int doubleList_printf(doubleList *list)
117 {
118     if (list == NULL || list->next == list)
119     {
120         return -1;
121     }
122
123     // 记录下一个节点
124     doubleList *tmp = list->next;
125
126     while (tmp != list)
127     {
128         printf("%d-", tmp->data);
129
130         tmp = tmp->next;
131     }
132     printf("\n");
133
134     return 0;
135 }
136
137 int main(void)
138 {
139     doubleList *list = NULL;
140     doubleList *node = NULL;
141     int i = 0;
142
143     list = doubleList_init();
144
145     for (i = 0; i < 10; i++)
146     {
147         doubleList_add_head(list, i);
148     }
149
150     doubleList_printf(list);
151
152     for (i = 0; i < 10; i++)
153     {
154         doubleList_add_tail(list, i);
155     }
156
157     doubleList_printf(list);
158
159     doubleList_del_head(list, &node);
160     printf("node:%d\n", node->data);
161     free(node);
162     node = NULL;
163
164     doubleList_printf(list);
165
166     doubleList_del_tail(list, &node);
167     printf("node:%d\n", node->data);
168     free(node);
169     node = NULL;
170
171     doubleList_printf(list);
172
173     return 0;
174 }
时间: 2024-10-09 23:53:29

05 双向链表的相关文章

笔试算法题(05):转换BST为双向链表 &amp; 查找栈中的最小元素

出题:把二元查找树转变成排序的双向链表.输入一棵二元查找树,要求将该二元查找树按照中序转换成一个排序的双向链表,要求不能创建任何新的节点,只能调整指针的指向: 分析: 递归的思路,当前节点需要进行的处理,并使用递归调用和返回值将子问题链接起来: 首先明白二元查找树的特性,变成有序双向链表后当前根节点的左节点为其原来左子树的最右节点,右节点为其原来右子树的最左节点:因此策略就是针对当前根节点索引的子树,首先判断其为上层节点的右子树还是左子树,从而决定返回最右还是最右节点:然后再递归处理当前根节点的

Java 集合系列05之 LinkedList详细介绍(源码解析)和使用示例

概要  前面,我们已经学习了ArrayList,并了解了fail-fast机制.这一章我们接着学习List的实现类——LinkedList.和学习ArrayList一样,接下来呢,我们先对LinkedList有个整体认识,然后再学习它的源码:最后再通过实例来学会使用LinkedList.内容包括:第1部分 LinkedList介绍第2部分 LinkedList数据结构第3部分 LinkedList源码解析(基于JDK1.6.0_45)第4部分 LinkedList遍历方式第5部分 LinkedL

(转)Java 集合系列05之 LinkedList详细介绍(源码解析)和使用示例

概要  前面,我们已经学习了ArrayList,并了解了fail-fast机制.这一章我们接着学习List的实现类——LinkedList.和学习ArrayList一样,接下来呢,我们先对LinkedList有个整体认识,然后再学习它的源码:最后再通过实例来学会使用LinkedList.内容包括:第1部分 LinkedList介绍第2部分 LinkedList数据结构第3部分 LinkedList源码解析(基于JDK1.6.0_45)第4部分 LinkedList遍历方式第5部分 LinkedL

linux内核-双向链表

linux中的经典宏定义 offsetof 定义:offsetof在linux内核的include/linux/stddef.h中定义. #define offsetof(TYPE, MEMBER) ((size_t) &((TYPE *)0)->MEMBER) 说明:获得结构体(TYPE)的变量成员(MEMBER)在此结构体中的偏移量. (01) ( (TYPE *)0 ) 将零转型为TYPE类型指针,即TYPE类型的指针的地址是0. (02) ((TYPE *)0)->MEMBER

.Net基础加强05

垃圾回收(先了解以后再研究) using System; using System.Collections.Generic; using System.Linq; using System.Text; using System.IO; namespace ConsoleApplication1 { class Program { static void Main(string[] args) { ////FileStream fs; ////fs.Dispose( //Person p1; #r

Linux内核中双向链表的经典实现

Linux内核中双向链表的经典实现 概要 前面一章"介绍双向链表并给出了C/C++/Java三种实现",本章继续对双向链表进行探讨,介绍的内容是Linux内核中双向链表的经典实现和用法.其中,也会涉及到Linux内核中非常常用的两个经典宏定义offsetof和container_of.内容包括:1. Linux中的两个经典宏定义2. Linux中双向链表的经典实现 转载请注明出处:http://www.cnblogs.com/skywang12345/p/3562146.html 更多

Linux中的两个经典宏定义:获取结构体成员地址,根据成员地址获得结构体地址;Linux中双向链表的经典实现。

倘若你查看过Linux Kernel的源码,那么你对 offsetof 和 container_of 这两个宏应该不陌生.这两个宏最初是极客写出的,后来在Linux内核中被推广使用. 1. offsetof 1.1 offsetof介绍 定义:offsetof在linux内核的include/linux/stddef.h中定义.#define offsetof(TYPE, MEMBER) ((size_t) &((TYPE *)0)->MEMBER) 说明:获得结构体(TYPE)的变量成员(

数据结构第四篇——线性表的链式存储之双向链表

?注:未经博主同意,不得转载. 前面讨论的单链表,每个结点中只有一个指针域,用来存放指向后继结点的指针,因此,从某个结点出发只能顺时针往后查找其他结点.若要查找某个结点的直接前驱,则需要从头指针开始沿链表探寻,处理起来十分不方便.为克服单链表的这一缺点,可引入双向链表. 双向链表中每一个结点含有两个指针域,一个指针指向其直接前驱结点,另一个指针指向直接后继结点.和单链表类似,双向链表一般也只有头指针唯一确定:同样也可设头结点,使得双向链表的某些操作简便一些. 双向链表结构定义如下:  双向链表是

我与小娜(05):变换时空,重返北京

我与小娜(05):变换时空,重返北京?       2月5日早上6点,我用手拍了一下“小口袋”,说:出来吧!小娜从袋子里面把紧闭的袋口打开,探出头来,看了我一眼,然后对着说:你是谁啊?       为什么小娜不认识我了?我是谁?……我也不记得自己是谁了?头脑里面一片空白,……突然之间,我明白了一个道理:物理因果关系是不能颠倒的,即便借助量子纠缠超距作用,也不能远距离传递传统信息,难怪小娜不认识我了,因为我的帐号没有传递给她.我自己也是头脑空白,一片无知,……       所幸的是,在小娜容身的“