数据结构代码题--头插法和尾插法的应用
头插法建立单链表(一般用于链表的逆置
)头插防断链 就是说用头插法时要给 p指针一个后继结点
// 单链表的定义 typedef struct LNode{ElemType data;struct LNode *next; }LNode,*LinkList; /*头插法建立单链表*/ LinkList Insert_Head(LinkList &L){LNode *s;int x;L = (LinkList)malloc(sizeof(LNode)); // 创建头结点 L->next = NULL; // 初始为空链表scanf("%d",&x);while(x!=-1){s = (LNode *)malloc(sizeof(LNode)); // 创建新结点s->data = x;s->next = L->next; // 将新结点插入表头 L->next = s; scanf("%d",&x);} return L; }
、2、尾插法建立单链表 尾插留尾指针 用尾插法时要有一个尾指针 r
// 单链表的定义 typedef struct LNode{ElemType data;struct LNode *next; }LNode,*LinkList; /*尾插法建立单链表*/ LinkList Insert_Head(LinkList &L){LNode *s;LNode *r; // 表尾指针 int x;L = (LinkList)malloc(sizeof(LNode)); // 创建头结点 r = L; scanf("%d",&x);while(x!=-1){s = (LNode *)malloc(sizeof(LNode)); // 创建新结点s->data = x;r->next = s;r = s; // r 指向新的表尾结点 scanf("%d",&x);} r->next = NULL; // 尾结点指针指向空 return L; }
1、单链表逆置
1、带头结点的单链表就地逆置 头插法
// 单链表的定义 typedef struct LNode{ElemType data;struct LNode *next; }LNode,*LinkList; /*算法思想:用头插法*/ LinkList Reverse(LinkList L){LNode *p = L->next;LNode *r; // P 的后继结点while(P->NULL){r = p->next; // 保留p的后继,防止断链 p->next = L->next; // 头插法 L->next = p;p = r;} return L; }
2、L={a1,a2,a3,……an}------>L={a1,an,a2,an-1,a3,an-2……}
typedef struct LNode{ElemType data;struct LNode *next; }LNode,*LinkList; /*算法思想: 找中间结点:两个指针同步从开头遍历,一个慢指针一次走一步,一个快指针一次走两步,当快指针到达表尾时,慢指针就刚好指向中间结点 后半段逆置:头插法 合并 :尾插法 */ void change_list(LinkList &L){LNode *p,*q,*r,*s;// 1、寻找中间结点 while(q->next!=NULL){p = p->next; // p走一步 q = q->next; // q走两步 if(q->nextQ=NULL){q = q->next;} }// 2、逆置(头插法) q = p->next; // 后半段链表,p为中间结点,q为后半段链表的首结点 while(q!=NULL){r = q->next; // 头插法,防止断链q->next = p->next;p->next = q;q = r; } // 3、从新合并s = L->next; // s指向前半段第一个结点,即插入点q = p->next; // q 指向后半段第一个结点 p->next = NULL;while(q!=NULL){r = q->next;q->next = s->next;s->next = q;s = q->next; // s指向前半段下一个插入点q = r; } }
2、链表归并与分解
1、将一个带头结点的单链表A分解为两个带头结点的单链表A和B,使得A表中保存序号是奇数的元素,B中保存序号是偶数的元素
// 单链表的定义 typedef struct LNode{ElemType data;struct LNode *next; }LNode,*LinkList; /*算法思想:不断的使用尾插法,序号奇数插入A,偶数插入B*/ LinkList Creat(LinkList &A){LNode *p = A->next;LinkList B = (LinkList)malloc(sizeof(LNode)); // 创建B链表 B->next = NULL; // B链表初始化 A->next = NULL; // 置空新的A链表 LNode *ra=A,*rb = B; // 两个尾指针 int i = 0; // 记录序号是奇数还是偶数 while(p!=NULL){i++;if(i%2 == 0){ // 偶数位插入B rb->next = p; // 尾插法 rb = p; }else{ // 奇数插入A ra->next = p;ra = p;}p = p->next;}ra->next = NULL; // 表尾指针指空 rb->next = NULL;return B; }
2、A={a1,b2,a2,b2……an,bn},采用带头结点的单链表存放,将其拆分为两个单链表A={a1,a2,……an},B={bn,bn-1,……b2,b1}
// 单链表的定义 typedef struct LNode{ElemType data;struct LNode *next; }LNode,*LinkList; /*算法思想:遍历A链表,将奇数位尾插入A中,偶数位头插入B中*/ LinkList Creat(LinkList &A){int i = 0;LNode *p = A->next,*q;LNode *ra = A;LinkList B = (LinkList)malloc(sizeof(LNode));B->next = NULL;A->next = NULL;while(p!=NULL){i++;if(i%2 == 0){ // 奇数位,头插入B q = p->next; // 头插法遍历原来的A链表时,保留p的后继结点,防止断链p->next = B->next;B->next = p;p = q; }else{ // 奇数位,尾插入A中 ra->next = p; // 尾插法 ra = p;p = p->next;}} ra->next = NULL;return B; }
3、将两个按元素值递增排序的单链表合并位一个按元素值递减排序的单链表
// 单链表的定义 typedef struct LNode{ElemType data;struct LNode *next; }LNode,*LinkList; /*算法思想:依次比较A和B中的值,将小的头插入到C中,如果其中一条链表有元素剩余,则依次进行头插入C中*/ void MergeList(LinkList &A,LinkList &B){LNode *p = A->next;LNode *q = B->next;LNode *t; // 防止断链 A->next = NULL // A置空 while(p!=NULL&&q!=NULL){if(p->data<=q->data){ // 将较小的头插入A中t = p->next; //头插法遍历原来的链表时,保留p的后继结点,防止断链p->next = A->next;A->next = p;p = q;}else{ // 将较小的B头插入A中t = q->next;q->next = A->next;A->next = q;q = t; }}while(p!=NULL){ // A中还有元素剩余,依次头插入A中 t = p->next; //头插法遍历原来的链表时,保留p的后继结点,防止断链p->next = A->next;A->next = p;p = q;}while(q!=NULL){ // B中还有元素剩余,依次头插入A中 t = q->next;q->next = A->next;A->next = q;q = t;} free(B); }
4、A,B为元素递增有序的单链表,找到A和B中的公共元素,存放到C中
// 单链表的定义 typedef struct LNode{ElemType data;struct LNode *next; }LNode,*LinkList; /*算法思想:遍历A和B链表,比较元素值,将元素值小的指针后移,将相等的元素值尾插法插入到C中*/ void Creat_Conmmon(LinkList A,LinkList B){LinkList C = (LinkList)malloc(sizeof(LNode)); // 创建C链表 C->next = NULL; // 初始化C链表 LNode *p = A->next;LNode *q = B->next;LNode *r = C;LNode *s; while(p!=NULL&&q!=NULL){if(p->data > q->data){ //更小的指针后移, q向后移 q = q->next; }else if(p->data < q->data){ // p向后移p = p->next; }else{ // 相同结点尾插法插入C中s = (LNode *)malloc(sizeof(LNode)); s->data = p->data;r->next = s;r = s;// p,q同时后移p = p->next;q = q->next; } } r->next = NULL; }
5、A,B两个单链表递增有序,求A,B的交集并存放于A中
// 单链表的定义 typedef struct LNode{ElemType data;struct LNode *next; }LNode,*LinkList; /*算法思想:依次扫描A,B两条链表,比较data域的值,将较小的指针向后移动(并释放空间),若 两者相等,则尾插入A中,直到遍历表尾,(若A链表还有元素剩余,则逐个释放剩余元素,只保留公共元素)*/ void Union(LinkList &A,LinkList &B){LNode *p = A->next;LNode *q = B->next;LNode *u;A->next = NULL; // A链表置空,重新插入元素 LNode *r = A;while(p!=NULL && q->next!=NULL){if(p->data < q->data){ // 元素小的指针后移,并释放空间 u = p;p = p->next;free(u);}else if(p->data > q->data){u = q;q = q->next;free(u);}else{ // 找到公共元素,保留一个,释放一个 r->next = p;r = p; // 保留p释放q;p = p->next;u = q;q = q->next;free(u); }}while(p!=NULL){ // A链表还存在元素,但是已经一定不含公共结点,依次释放空间 u = p;p = p->next;free(u);}while(q!=NULL){ // B链表还有元素 u = q;q = q->next;free(u);}r->next = NULL;free(B); }
4、寻找相同子序列
1、两个整数子序列A = a1,a2……an B= b1,b2,……bn,存放到两个单链表中,判断序列B是否为A的连续子序列
// 单链表的定义 typedef struct LNode{ElemType data;struct LNode *next; }LNode,*LinkList; /*算法思想:暴力法:类似字符串的模式匹配,依次遍历A和B链表,如果data值相同,同时后移,如果不相同 A返回开始比较结点的后继结点,B则从头开始 */ bool Pattern(LinkList A,LinkList B){LNode *p = A->next;LNode *q = B->next;LNode *pre = p;while(p!=NULL&&q!=NULL){if(p->data == q->data){ // 结点值相同,两个结点同时向后移p = p->next;q = q->next; }else{pre = pre->next; // p = pre; // A返回开始比较结点的后继结点q = B->next; // B则从头开始 } }if(q == NULL){ // B中没有元素了,说明B是A的自序列 return true;}else{return false;}}
数据结构代码题--头插法和尾插法的应用相关推荐
- 数据结构—分别用头插法和尾插法建立单链表
#include <iostream> using namespace std; typedef struct LNode{int data;struct LNode *next; }LN ...
- 数据结构学习(二)——单链表的操作之头插法和尾插法创建链表
http://blog.csdn.net/abclixu123/article/details/8210109 链表也是线性表的一种,与顺序表不同的是,它在内存中不是连续存放的.在C语言中,链表是通过 ...
- C语言的双向链表头插法和尾插法,指定节点删除
文章目录 前言 头插法 尾插法 删除节点 测试代码如下 前言 双向链表和单链表的唯一区别就是多个一个指针域而已,该指针域可以访问链表的上一个节点. 关于构造双向链表的过程我们常见的有两种方法,和单链表 ...
- 头插法和尾插法创建链表(有无头结点)
头插法和尾插法创建链表(有无头结点) 文章目录 头插法和尾插法创建链表(有无头结点) 1 头插法 1.1头插法建表规则: 1.2 头插法建表代码实现 2 尾插法 2.1 尾插法建表规则: 2.2 尾插 ...
- 双向循环链表的头插法和尾插法
我们平常学链表的时候会学单向不循环链表,单向循环链表,双向不循环链表,双向循环链表及内核链表,各种格式的链表.今天我因为忘记双向循环链表的头插法和尾插法的顺序了,特意写一篇文章来巩固一下.首先我根据顺 ...
- 头插法和尾插法建立带头节点的单链表
有两种方法建立单链表,尾插法和头插法,他们的区别是:头插法是按照输入元素倒序建立,为尾插法为顺序插入,并且多一个尾节点,我们一般使用尾插法. 一.头插法 代码为: pCurr -> next = ...
- c语言 链表建立头插法尾插法,单链表的创建(头插法和尾插法)
单链表的创建分为头插法和尾插法,头插法是不断地向头结点插入新的结点.这样会使你所插入的结点值呈现逆序,所以头插法也可以实现单链表的逆置.尾插法是不断地向插入的新元素之后再插入新的元素.需要注意的是头插 ...
- 计算机软件技术 上海电力学院,上海电力学院 计算机软件技术 实验三 用头插法和尾插法创建线性表...
上海电力学院计算机软件技术实验三用头插法和尾插法创建线性表 #include #define MAXLEN 9 struct table {int key; int othererm; } ; typ ...
- 单链表的头插法和尾插法c语言实现
/*单链表的头插法和尾插法c语言实现*/ #include <stdio.h> #include <stdlib.h> #include <string.h> #d ...
最新文章
- CIR,CBS,EBS,PIR,PBS傻傻分不清楚?看这里!—-揭秘令牌桶
- Oracle数据库之SQL连接查询
- 计算机组成要素六:编译器 语法分析器
- Docker中Maven私服的搭建
- Nginx 502 Bad Gateway 错误的原因及解决方法
- php的控制器,php-模块与控制器
- Mysql批量更新的三种方式
- mysql 字符,索引
- 五大“领跑者”光伏基地概览
- 面料经纬向、正反面判别方法
- 【java】JOptionPane的几种方法的作用
- 【读书笔记《Android游戏编程之从零开始》】7.Android 游戏开发常用的系统控件(Dialog)
- 数据集制作——使用labelimg制作数据集
- STEAM 正在检查可用更新 ,失败
- pdf用什么软件打开
- 查询各科成绩的前三名的学生
- 管理故事:无知的小沙弥
- 【web前端】第二天-HTML标签(下)
- iOS 15 导航栏(Navigation)变白(导航栏不见)
- 链表及经典问题(船长系列)