chunlanse2014

导航

< 2025年3月 >
23 24 25 26 27 28 1
2 3 4 5 6 7 8
9 10 11 12 13 14 15
16 17 18 19 20 21 22
23 24 25 26 27 28 29
30 31 1 2 3 4 5

统计

2.3线性表的链式存储和运算—单链表应用举例

例2.5 已知单链表H,写一算法将其倒置。即实现如图2.22的操作。(a)为倒置前,(b)为倒置后。


算法思路:依次取原链表中的每个结点,将其作为第一个结点插入到新链表中去,指针p用来指向当前结点,p为空时结束。

算法如下:

复制代码
 1 void reverse (Linklist H)
 2 { 
 3     LNode *p;
 4     p=H->next;             /*p指向第一个数据结点*/
 5     H->next=NULL;          /*将原链表置为空表H*/
 6     while (p)              /*p结点不为空,循环*/
 7     { 
 8         q=p;               /*用另一个结点q存储p结点的信息*/
 9         p=p->next;         /*不断后移*/
10         q->next=H->next;   /*将当前结点插到头结点的后面*/
11         H->next=q;         /*将头结点与当前结点相连*/
12     }
13 }
复制代码

算法2.15

该算法只是对链表中顺序扫描一边即完成了倒置,所以时间性能为O(n)。

例2.6 已知单链表L,写一算法,删除其重复结点,即实现如图2.23的操作。(a)为删除前,(b)为删除后。

算法思路:用指针p 指向第一个数据结点,从它的后继结点开始到表的结束,找与其值相同的结点并删除之;p 指向下一个;依此类推,p 指向最后结点时算法结束。

算法如下:

复制代码
 1 void pur_LinkList(LinkList H)
 2 { 
 3     LNode *p,*q,*r;
 4     p=H->next; /*p指向第一个结点*/
 5     if(p==NULL) 
 6         return;
 7     while (p->next)
 8     { 
 9         q=p;
10         while (q->next) /* 从*p的后继开始找重复结点*/
11         { 
12             if (q->next->data==p->data)
13             { 
14                 r=q->next; /*找到重复结点,用r指向,删除*r */
15                 q->next=r->next;
16                 free(r);
17             } 
18             else 
19                 q=q->next;
20         } 
21         p=p->next; /*p指向下一个,继续*/
22     } 
23 }
复制代码

算法2.16

该算法的时间性能为O(n2)。

例2.7 设有两个单链表A、B,其中元素递增有序,编写算法将A、B归并成一个按元素值递减(允许有相同值)有序的链表C,要求用A、B中的原结点形成,不能重新申请结点。

算法思路:利用A、B两表有序的特点,依次进行比较,将当前值较小者摘下,插入到C表的头部,得到的C表则为递减有序的。

算法如下:

复制代码
 1 LinkList merge(LinkList A,LinkList B)
 2 /*设A、B均为带头结点的单链表*/
 3 { 
 4     LinkList C; 
 5     LNode *p,*q;
 6     p=A->next;       /*A的第一个结点*/
 7     q=B->next;       /*B的第一个结点*/
 8     C=A;             /*C表的头结点*/
 9     C->next=NULL;    /*C表置空*/
10     free(B);         /*释放B的头结点*/
11     while (p&&q)     /*p和q结点都存在*/
12     { 
13         if(p->data<q->data)         /*从原AB表上摘下较小者*/
14         { 
15             s=p;                    /*临时结点s指向p*/
16             p=p->next; 
17         }
18         else    
19         {
20             s=q;
21             q=q->next;
22         } 
23         s->next=C->next;   /*C表的第一个结点赋给结点s的后继*/
24         C->next=s;         /*将结点s赋给C表头结点的后继*/
25     } 
26     if (p==NULL) 
27         p=q;
28     while (p)              /* 将剩余的结点一个个摘下,插入到C表的头部*/
29     { 
30         s=p;
31         p=p->next;
32         s->next=C->next;
33         C->next=s;
34     }
35 }
复制代码

算法2.17

该算法的时间性能为O(m+n)。

posted on   chunlanse2014  阅读(509)  评论(0编辑  收藏  举报

(评论功能已被禁用)
编辑推荐:
· AI与.NET技术实操系列:基于图像分类模型对图像进行分类
· go语言实现终端里的倒计时
· 如何编写易于单元测试的代码
· 10年+ .NET Coder 心语,封装的思维:从隐藏、稳定开始理解其本质意义
· .NET Core 中如何实现缓存的预热?
阅读排行:
· 分享一个免费、快速、无限量使用的满血 DeepSeek R1 模型,支持深度思考和联网搜索!
· 基于 Docker 搭建 FRP 内网穿透开源项目(很简单哒)
· 25岁的心里话
· ollama系列01:轻松3步本地部署deepseek,普通电脑可用
· 按钮权限的设计及实现
点击右上角即可分享
微信分享提示