单链表和双链表 算法与实现
2010-04-14 11:56
253 查看
链表是包含一些数据的独立数据结构(也成为节点)的集合,每个节点都是通过指针链接在一起的。通常节点是动态分配的。事实上,链表中的节点可以存在于内存中的各个地方。,所以在物理上是不是相邻并无影响。
链表在数据结构中占有很大的作用,它可以根据使用情况分配内存,避免内存的浪费。它的插入,删除,查找都是根据指针的访问来实现,删除或添加一个节点不会改变其他数据的位置和内容,和数组相比,链表具有很强的灵活性和可操作性,但是在使用和实现的时候稍微麻烦,而且比较抽象。
单链表
在单链表中,每个节点都包含指向下一个节点的指针,最后一个节点的指针为NULL,以标志最后一个节点。之所以叫单链表也是因为每个节点只存在一个节点指针而已,所以只能顺序访问下一个节点,俗话就是过了这个村就没这个店了。为了记住单链表的第一个位置,可以定义一个头指针head。
单链表的节点创建如下
创建之后,NODE就是节点的数据类型,它是一个包含一个整形数和一个节点指针的封装数据。
建立单链表的函数算法实现
建立单链表中,函数是一个指针函数,指针类型是节点,它最终的返回值是头节点。函数里建立了三个节点指针,分别是头节点指针,当前节点指针和前一个节点指针。先建立头指针,数据为0,指针为NULL。通过传递给该函数的参数n来确定节点的个数。在n个循环内一直建立当前节点,当前节点的数据键盘输入,当前节点指针为空。前一节点的指针指向当前节点,最后把当前指针替换为前一个指针进行下一次循环。
单链表中插入节点算法(在第i个节点之前)
函数中,先遍历节点,直到找到需要添加节点的位置,如果遍历到最后一个节点,函数返回,如果跳出遍历循环,说明是插入位置,申请一个新的节点,数据为x,指针指向当前节点指向的后一个节点,当前节点(实际上已经是旧的节点)指向新节点。
单链表中的删除算法
函数中,先遍历节点,直到找到需要删除节点的位置,将需要删除的节点前一个节点的指针指向其后一个节点,释放内存。
双向链表
顾名思义,双向链表比单链表的多出了一个节点指针,用来指向前一个节点的数据,这样做的好处不言而喻,避免了寻找前面节点时候发生的不方便之举。在数据结构里后面节点称为后继,前面的节点称为前驱。
下面用C描述一下双向链表的建立
实际上,双向链表仅仅加入的前向指针,前向指针指向的是前一个节点,而前一个指针的后向指针也是指向后一个节点,通过这种方式实现了前后访问。单链表理解了之后,双链表理解起来也很简单,原理是差不多的。
双链表的插入算法
双链表的删除算法
链表在数据结构中占有很大的作用,它可以根据使用情况分配内存,避免内存的浪费。它的插入,删除,查找都是根据指针的访问来实现,删除或添加一个节点不会改变其他数据的位置和内容,和数组相比,链表具有很强的灵活性和可操作性,但是在使用和实现的时候稍微麻烦,而且比较抽象。
单链表
在单链表中,每个节点都包含指向下一个节点的指针,最后一个节点的指针为NULL,以标志最后一个节点。之所以叫单链表也是因为每个节点只存在一个节点指针而已,所以只能顺序访问下一个节点,俗话就是过了这个村就没这个店了。为了记住单链表的第一个位置,可以定义一个头指针head。
单链表的节点创建如下
typedef struct Linear_chain_node { int data; struct Linear_chain_node *link; } NODE;
创建之后,NODE就是节点的数据类型,它是一个包含一个整形数和一个节点指针的封装数据。
建立单链表的函数算法实现
NODE *Creat_single_chain(int n) { NODE *head , *current,*previous; int i; previous=(NODE*)malloc(sizeof(NODE)); previous->data = 0; previous->link = NULL; head = previous ; for(i=0;i<n;i++) { current = (NODE*)malloc(sizeof(NODE)); scanf("%d",current->data); current->link = NULL; previous->link = current; previous = current; } return head; }
建立单链表中,函数是一个指针函数,指针类型是节点,它最终的返回值是头节点。函数里建立了三个节点指针,分别是头节点指针,当前节点指针和前一个节点指针。先建立头指针,数据为0,指针为NULL。通过传递给该函数的参数n来确定节点的个数。在n个循环内一直建立当前节点,当前节点的数据键盘输入,当前节点指针为空。前一节点的指针指向当前节点,最后把当前指针替换为前一个指针进行下一次循环。
单链表中插入节点算法(在第i个节点之前)
int Insert(NODE *head , int i , int x) { NODE *current , *new ; int j; if(i<=0) retuen 0; current = head; j = 0; while((j<i-1) && current != NULL) { current = current->link; j++; } if(current = NULL) return 0; new = (NODE*)malloc(sizeof(NODE)); new->data = x; new->link = current->link; current->link = new; return 1; }
函数中,先遍历节点,直到找到需要添加节点的位置,如果遍历到最后一个节点,函数返回,如果跳出遍历循环,说明是插入位置,申请一个新的节点,数据为x,指针指向当前节点指向的后一个节点,当前节点(实际上已经是旧的节点)指向新节点。
单链表中的删除算法
int Delete(NODE *head , int i) { NODE *previous , *current ; int j=1; if(i<1) return 0; previous = head; while((j<i) && previous->link != NULL) { previous = previous->link; j++; } if(previous->link == NULL) return 0; current = previous->link; previous->link = current->link; free(current); return 1 }
函数中,先遍历节点,直到找到需要删除节点的位置,将需要删除的节点前一个节点的指针指向其后一个节点,释放内存。
双向链表
顾名思义,双向链表比单链表的多出了一个节点指针,用来指向前一个节点的数据,这样做的好处不言而喻,避免了寻找前面节点时候发生的不方便之举。在数据结构里后面节点称为后继,前面的节点称为前驱。
下面用C描述一下双向链表的建立
实际上,双向链表仅仅加入的前向指针,前向指针指向的是前一个节点,而前一个指针的后向指针也是指向后一个节点,通过这种方式实现了前后访问。单链表理解了之后,双链表理解起来也很简单,原理是差不多的。
双链表的插入算法
int Insert(NODE *head , int x , int y) { NODE *current, *new; current = head->flink; while((current != head) && (current->data != y)) current=current->flink; if(current == head) return 0; new = (NODE*)malloc(sizeof(NODE)); new->data = x; new->blink = current; new->flink = current->flink; (current->flink)->blink = new; current->flink->new; return 1; }
双链表的删除算法
int Delete(NODE *head,int x) { NODE *current; current = head->flink; while((current != head) && (current->data != x)) current=current->flink; if(current == head) return 0; (current->blink)->flink = current->flink; (current->flink)->vlink = current->blink; free(current); return 1; }
typedef struct double_chain_node { int data; struct double_chain_node *blink,*flink; }NODE; NODE *Ceate_double_chain(int n) { int i; NODE *head , *previous ,*current; previous = (NODE*)malloc(sizeof(NODE)); previous->data = 0; previous->blink = previous->flink = NULL; head = previous; for(i=0;i<n;i++) { current = (NODE*)malloc(sizeof(NODE)); scanf("%d",¤t->data); current->flink = NULL; current->blink = previous; previous->flink = current; previous = current; } return head; }
相关文章推荐
- 【算法设计-单链表的逆转】单链表逆转实现
- 面试-链表逆置 作业手写一个单链表,并且实现单链表元素的逆置,(a0, a1,a2,a3,..an)-> (an,an-1,… a1, a0),算法的空间复杂度和时间复杂度经可能低
- 设单链表以非递减有序排列,设计算法实现在单链表中删去值相同的多余结点。
- 从键盘读入n个整数(升序),请编写算法实现: 建立带表头结点的单链表; 显示单链表,(形如:H->10->20->30->40); 在有序单链表中插入新的数据元素x; 将单链表就地逆
- 【数据结构和算法】用java简单的实现单链表的基本操作
- 顺序表、单链表、循环单链表、循环双链表、有序单链表的排序的实现
- 链表系列之单链表——使用单链表实现大整数相加
- 数据结构算法代码实现——线性表的链式表示与实现(单链表)(三 )
- Java单链表反转 Java实现单链表翻转
- 计算带头结点单链表的长度 计算单链表的长度,实现单链表的打印
- Java中单链表的实现和单链表的反转(倒置)
- 每天一算法(一)——用链表实现加减乘运算
- 链表反转算法-java实现
- 【LeetCode-面试算法经典-Java实现】【086-Partition List(将单链表进行分区)】
- 图的邻接链表实现下的搜索两点之间所有路径的算法
- 数据结构——单链表(链表操作算法集合)
- 实现一个算法,删除单链表中间的某个结点,假定你只能访问该结点
- 数据结构之链表:实现单链表的逆序 (1)
- 基本算法实现小结(一)—— 单链表
- C++实现两个有序链表合并(17)---《那些奇怪的算法》