单链表运算
来源:互联网 发布:阿里吧最新软件 编辑:程序博客网 时间:2024/06/06 12:58
一 建立单链表
延续前面的定义,数据取字符型,以/n作为输入结束条件,动态建立单链表通常分为头插法和尾插法,下面将一一描述。
(1)头插法
算法思路:将新节点插入到当前节点的头部,直到读入结束标志符为止
这种方式生成的链表节点次序与输入的次序相反
头插法具体算法代码
<pre name="code" class="cpp">LinkList CreatListH(void){char ch;LinkList head;//头指针ListNode *s;//工作指针head = NULL;//链表开始为空ch = getchar();//读取第一个字符while(ch!='\n'){s = (ListNode *)malloc(sizeof(ListNode));//生成新的节点if(!s){printf("申请内存失败");return NULL;}s->data = ch; //将读入的数据放入新节点数据域s->next = head;head = s;ch = getchar(); //读入下一个字符}return head;}
(2)尾插法
算法思路:将新节点当前节点的尾部,直到读入结束标识符
这种方式生成的链表顺序与输入顺序一致,但是需要增加一个尾指针r,使其始终指向当前节点的尾节点
尾插法具体算法代码
LinkList CreatListT(void){char ch;LinkList head;//头指针ListNode *s,*r;//工作指针head = NULL;//链表开始为空r = NULL;ch = getchar();//读入第一个字符while(ch!='\n'){s = (ListNode *)malloc(sizeof(ListNode));//生成新节点if(!s){printf("申请内存失败");return NULL;}s->data = ch;//将读入的数据放入新节点的数据域if(head==NULL)head = s;//将新节点插入空表elser->next = s;//将新节点插入到*r之后ch = getchar();//读入下一个字符}if(r!=NULL)r->next = NULL;//对于非空表,将表尾指向指针域,置空head=sreturn head;}
注:以上俩个方法时间复杂度均为O(n)
二 单链表查找
(1)按序号查找
计数器j置为0后,扫描指针p指针从链表的头结点开始顺着链扫描。当p扫描下一个结点时,计数器j相应地加1。当j=i时,指针p所指的结点就是要找的第i个结点。而当p指针指为null且j≠i时,则表示找不到第i个结点。
注意:头结点可看做是第0个结点。
算法思想:
ListNode * GetNode(LinkList head,int i){//在带头结点的单链表head中查找第i个结点,若找到(0≤i≤n), //则返回该结点的存储位置,否则返回NULLint j;ListNode *p;p = head,j = 0;//从头开始扫描while(p->next&&j<i){p = p->next;j++;}if(i==j)return p;//找到了第i个结点else return NULL;}算法分析:
最多距离为i,这与气位置有关,在等概率假设情况下,平均时间复杂度为
(2)按值查找
算法思想:
ListNode * LocateNode(ListNode head,DataType key){ListNode *p = head->next;//设置开始比较的节点while(p&&p->data!=key)//直到p为NULL或者p->data为keyp = p->next;//扫描下一个节点return p;}
算法分析:
该算法的执行时间亦与输入实例中key的取值相关,其平均时间复杂度分析类似于按序号查找,为O(n)。
三 插入运算
插入运算思想 :将值为x的新结点插入到表的第i个结点的位置上,即插入到ai-1与ai之间。
具体步骤:
(1)找到ai-1存储位置p
(2)生成一个数据域为x的新结点*s
(3)令结点*p的指针域指向新结点
(4)新结点的指针域指向结点ai。
具体算法实现 :
void InsertList(LinkList head,DataType x,int i){//将值为x的新节点插入到带头结点单链表head//的第i个节点位置ListNode *p;p = GetNode(head,i-1);//寻找第i-1个节点if(p==NULL)Error("position error");s = (ListNode *)malloc(sizeof(ListNode));s->data = x;s->next = p->next;p->next = s;}
算法分析:
主要集中在GetNode上,因此时间复杂度仍旧为O(n)
四 删除运算
具体步骤:
(1)找到ai-1的存储位置p(因为在单链表中结点ai的存储地址是在其直接前趋结点ai-1的指针域next中)
(2)令p->next指向ai的直接后继结点(即把ai从链上摘下)
(3)释放结点ai的空间,将其归还给"存储池"。
记得释放内存就好
具体算法实现:
void DeleteList(LinkList head ,int i){//删除带头结点的第i个节点ListNode *p,*r;p = GetNode(head,i-1);//找到第i-1个节点if(p==NULL||p->next==NULL)Error("position error");r = p->next;//r指向被删除结点的aip->next = r->next;//将ai从链上取下free(r);//释放节点}
算法分析:
时间复杂度也是O(n)
- 单链表运算
- 单链表运算
- 单链表的基本运算
- 单链表的运算实现
- 单链表的基本运算
- 单链表的基本运算
- 单链表的运算
- 单链表的运算
- 单链表的基本运算
- 10.4单链表基本运算
- “<<”运算“+ - * /”
- && || 运算
- 运算
- 运算
- 运算^
- 运算
- 运算
- &运算
- 六类UML图
- go中利用hmset替换hset来提高redis的存取效率及并发goroutine可能遇到的问题
- hdu 4405 Aeroplane chess (概率dp)
- CentOS启动后直接进入命令行模式
- 当你输入一个网址的时候,实际会发生什么?
- 单链表运算
- 百度是如何给每个人免费提供2TB存储空间的?
- There is no Action mapped for namespace [/] and action name [viewLogAction] associated with context
- C函数调用与堆栈的变化
- hibernate注解大全
- iOS 开发,工程中混合使用 ARC 和非ARC
- 从顺序表L中删除元素x到y之间的所有元素(x<=y)
- php返回json数据函数例子
- 在你往浏览器中输入一个URL后都发生了什么