单链表运算

一 建立单链表

延续前面的定义,数据取字符型,以/n作为输入结束条件,动态建立单链表通常分为头插法和尾插法,下面将一一描述。

(1)头插法

算法思路:将新节点插入到当前节点的头部,直到读入结束标志符为止

这种方式生成的链表节点次序与输入的次序相反

头插法具体算法代码

[cpp] view plain copy

 

  1. <pre name="code" class="cpp">LinkList CreatListH(void)  
  2. {  
  3.     char ch;  
  4.     LinkList head;//头指针  
  5.     ListNode *s;    //工作指针  
  6.     head = NULL;    //链表开始为空  
  7.     ch = getchar(); //读取第一个字符  
  8.     while(ch!='\n')  
  9.     {  
  10.         s = (ListNode *)malloc(sizeof(ListNode));//生成新的节点  
  11.         if(!s)  
  12.         {  
  13.             printf("申请内存失败");  
  14.             return NULL;  
  15.         }  
  16.                 s->data = ch; //将读入的数据放入新节点数据域  
  17.                 s->next = head;head = s;  
  18.                 ch = getchar(); //读入下一个字符  
  19.         }  
  20.                 return head;  
  21. }  



(2)尾插法

算法思路:将新节点当前节点的尾部,直到读入结束标识符

这种方式生成的链表顺序与输入顺序一致,但是需要增加一个尾指针r,使其始终指向当前节点的尾节点

尾插法具体算法代码

[cpp] view plain copy

 

  1. LinkList CreatListT(void)  
  2. {  
  3.     char ch;  
  4.     LinkList head;//头指针  
  5.     ListNode *s,*r;//工作指针  
  6.     head = NULL;    //链表开始为空  
  7.     r = NULL;  
  8.     ch = getchar(); //读入第一个字符  
  9.     while(ch!='\n')  
  10.     {  
  11.         s = (ListNode *)malloc(sizeof(ListNode));//生成新节点  
  12.         if(!s)  
  13.         {  
  14.             printf("申请内存失败");  
  15.             return NULL;  
  16.         }  
  17.         s->data = ch;//将读入的数据放入新节点的数据域  
  18.         if(head==NULL)  
  19.             head = s;   //将新节点插入空表  
  20.         else  
  21.             r->next = s;//将新节点插入到*r之后  
  22.         ch = getchar();//读入下一个字符  
  23.     }  
  24.     if(r!=NULL)  
  25.         r->next = NULL;//对于非空表,将表尾指向指针域,置空head=s  
  26.     return head;  
  27. }  

注:以上俩个方法时间复杂度均为O(n)

二 单链表查找

(1)按序号查找

计数器j置为0后,扫描指针p指针从链表的头结点开始顺着链扫描。当p扫描下一个结点时,计数器j相应地加1。当j=i时,指针p所指的结点就是要找的第i个结点。而当p指针指为null且j≠i时,则表示找不到第i个结点。
注意:头结点可看做是第0个结点。

算法思想:

[cpp] view plain copy

 

  1. ListNode * GetNode(LinkList head,int i)  
  2. {  
  3.     //在带头结点的单链表head中查找第i个结点,若找到(0≤i≤n),  
  4.       //则返回该结点的存储位置,否则返回NULL  
  5.     int j;  
  6.     ListNode *p;  
  7.     p = head,j = 0;//从头开始扫描  
  8.     while(p->next&&j<i){  
  9.         p = p->next;  
  10.         j++;  
  11.     }  
  12.     if(i==j)  
  13.         return p;//找到了第i个结点  
  14.     else   
  15.         return NULL;  
  16. }  

算法分析:

最多距离为i,这与气位置有关,在等概率假设情况下,平均时间复杂度为

(2)按值查找

算法思想:

[cpp] view plain copy

 

  1. ListNode * LocateNode(ListNode head,DataType key)  
  2. {  
  3.     ListNode *p = head->next;//设置开始比较的节点  
  4.     while(p&&p->data!=key)//直到p为NULL或者p->data为key  
  5.         p = p->next;//扫描下一个节点  
  6.     return  p;  
  7. }  

算法分析:

 该算法的执行时间亦与输入实例中key的取值相关,其平均时间复杂度分析类似于按序号查找,为O(n)。

三 插入运算

插入运算思想 :将值为x的新结点插入到表的第i个结点的位置上,即插入到ai-1与ai之间。

具体步骤: 
(1)找到ai-1存储位置p
(2)生成一个数据域为x的新结点*s
(3)令结点*p的指针域指向新结点
(4)新结点的指针域指向结点ai。

具体算法实现 :

[cpp] view plain copy

 

  1. void InsertList(LinkList head,DataType x,int i)  
  2. {  
  3.     //将值为x的新节点插入到带头结点单链表head  
  4.     //的第i个节点位置  
  5.     ListNode *p;  
  6.     p = GetNode(head,i-1);//寻找第i-1个节点  
  7.     if(p==NULL)  
  8.         Error("position error");  
  9.     s = (ListNode *)malloc(sizeof(ListNode));  
  10.     s->data = x;  
  11.     s->next = p->next;  
  12.     p->next = s;  
  13. }  

算法分析:

主要集中在GetNode上,因此时间复杂度仍旧为O(n)

四  删除运算

具体步骤: 
(1)找到ai-1的存储位置p(因为在单链表中结点ai的存储地址是在其直接前趋结点ai-1的指针域next中)
(2)令p->next指向ai的直接后继结点(即把ai从链上摘下)
(3)释放结点ai的空间,将其归还给"存储池"。
记得释放内存就好

具体算法实现:

[cpp] view plain copy

 

  1. void DeleteList(LinkList head ,int i)  
  2. {  
  3.     //删除带头结点的第i个节点  
  4.     ListNode *p,*r;  
  5.     p = GetNode(head,i-1);//找到第i-1个节点  
  6.     if(p==NULL||p->next==NULL)  
  7.         Error("position error");  
  8.     r  = p->next;//r指向被删除结点的ai  
  9.     p->next = r->next;//将ai从链上取下  
  10.     free(r);//释放节点  
  11. }  

算法分析:

时间复杂度也是O(n)

[cpp] view plain copy

  1.   

转载:http://blog.csdn.net/xsf50717/article/details/39899193

时间: 2024-09-06 14:07:05

单链表运算的相关文章

数据结构模版----单链表实现方式总结

数据结构模版----单链表实现方式总结 前面我们提供了四种方式实现的单链表,有带头结点的不带头结点的,而单链表的结构体定义也有两种方式,那么这些实现方式,到底有什么区别呢,为什么会出现这么多种实现方式呢,下面我们就来细细体会 一 单链表结构体的实现区别 首先我们对比一下,单链表结构体 不同方式的单链表实现时,链表结点的实现是相同的,不同之处在于单链表结构体的实现上 单链表结构体的实现 [cpp] view plain copy print? typedef int ElemType;      

单链表的实现

在单链表中,我们需要在内部有一个头节点,我们可以通过这个头节点找到其他的节点,相当于一个线索. 纵观顺序结构的线性表和单链表的实现,难点基本上都在于添加和删除操作.基于数组的线性表中,数组的索引就相当于是线性表的序号,但在单链表中,我们没有序号这个东西,所以在添加和删除操作中,我们需要先找到指定的元素,然后才能继续进行操作.在插入操作中,我们需要同时保存有当前节点的前一个节点和当前的节点,因为当前要插入的节点要放在前一个节点的Next引用域,而当前节点要放在要插入节点的next域.删除节点与此相

单链表的顺序-c++正序与逆序创建单链表有什么区别

问题描述 c++正序与逆序创建单链表有什么区别 c++正序与逆序创建单链表有什么本质的区别,逆序比顺序的优点体现在哪? 解决方案 逆序没什么特别的好处,给你学编程的时候练练手玩的,在实际的项目中会用到标准库,那是双向链表,没有逆序创建一说. 要说逆序的好处:当要加入新的数据时,不需要遍历链表,可以直接在头结点之后插入即可,减少时间复杂度 解决方案二: 没有太大价值吧......不过双向的链表应用很广泛 解决方案三: 逆序创建单链表

java单链表常用操作

总结提高,与君共勉 概述. 数据结构与算法亘古不变的主题,链表也是面试常考的问题,特别是手写代码常常出现,将从以下方面做个小结 [链表个数] [反转链表-循环] [反转链表-递归] [查找链表倒数第K个节点] [查找链表中间节点] [判断链表是否有环] [从尾到头打印单链表-递归] [从尾到头打印单链表-栈] [由小到大合并有序单链表-循环] [由小到大合并有序单链表-递归] 通常在Java中这样定义单链表结构 [java] view plain copy <span style="fon

用java学习数据结构--单链表

数据|数据结构 /* * Created on 2004-9-10 * * 单链表中的结点类型声明. */package org.arliang;/** * @author 李梁 * * 单链表中的结点. */public class node{ private int data; //存放数据 private node link; //链接的下一个接点. public static void main(String[]args) { } /** * @return Returns the da

数据结构(C#):单链表

与顺序表相比,链表有自己的特点:插入.删除操作无需移动元素:能够高效实现动态内存分配:但 不能按节点索引快速定位到节点:由于需要记录指针域,系统开销较大. 本篇介绍单链表的实现,使用上一篇定义的接口. 代码: /* * File : SingleLinkedList.cs * Author : Zhenxing Zhou * Date : 2008-12-06 * Blog : http://www.xianfen.net/ */ using System; using System.Colle

大话数据结构二:线性表的链式存储结构(单链表)

1. 线性表的链式存储结构:指的是用一组任意的存储单元存储线性表的数据元素,这组存储单元可以是连续的,也可以是不连续的,这就意味着这些数据元素可以存在内存未被占用的任意位置. 2. 结点:结点由存放数据元素的数据域和存放后继结点地址的指针域组成. 1.)顺序存储结构中,每个数据元素只需要存数据元素的信息就可以了. 2.)链式存储结构中,除了要存储数据元素信息外,还要存储它的后继元素的存储地址. 3.)链表中第一个结点叫头结点,它的存储位置叫做头指针,它的数据域可以不存储任何信息,链表的最后一个结

单链表相关算法

[1]打印单链表,void PrintList(List list); 使用一个指针遍历所有链表节点. [2]两个升序链表,打印tarList中的相应元素,这些元素的序号由SeqList指 定,void PrintLots(List tarList, List seqList); 使用两个指针分别遍历两个链表,每次取出序列链表的一个序号后,根据该 序号,到达目标链表指定节点. [3]两个升序链表交集 ,List Intersect(List l1, List l2); [4]两个升序链表并集 ,

数据结构学习(C++)之单链表

节点类 #ifndef Node_H#define Node_Htemplate <class Type> class Node //单链节点类{ public: Type data; Node<Type> *link; Node() : data(Type()), link(NULL) {} Node(const Type &item) : data(item), link(NULL) {} Node(const Type &item, Node<Type&