单链表
线性表的链式表示和实现
1.线性链表
1).单链表定义线性表的思想
线性表的链式存储又称单链表。为了建立数据元素之间的线性关系,对每个链表节点,除存放自身数据外,还存放一个指向后继的指针。也称线性链表。
一个链表由n个节点组成。
单链表节点的结构特点:
data | next |
---|
data 为数据域部分,用于存储数据。 next 为指针域部分,用于指向后继。
指针为数据元素之间的逻辑关系的映像,则逻辑上相邻的两个元素其存储的物理位置不要求紧邻,因此这种存储结构为非顺序映像或链式映像。
利用单链表可以解决顺序表需要大量连续存储单元的缺点,由于单链表的元素离散地分布在存储空间中,所以单链表是非随机存取的存储结构,即不能直接找到表中某个特定元素,要查找某个元素,必须从表头开始遍历。
通常用头指针来标识一个单链表
带头节点的单链表
不带头节点的单链表
2).单链表定义线性表的结构体
typedef struct LNode{
int data;
struct LNode*next; //定义后继节点
}LNode,*LinkList;
3).单链表定义线性表的基本操作
#建立新链表
头插法建立单链表
头插法思想:
带头节点:
把新节点插在头节点的后面。
操作:让新节点指针域指向头结点指针域指向的节点,再让头结点指针域指向新节点。
不带头结点:
把新节点插在头部。
操作:新节点指针域指向头指针指向的节点,再让头指针指向新节点。
带头节点,使用头插法建立新链表
/*带头节点建立新链表,头插法*/
LinkList Header_insert(LinkList &L)
{
LNode *p; int x;
L = (LinkList)malloc(sizeof(LNode)); //创建头节点
L->next = NULL; //指针域为空
printf("输入插入值:\n"); //输入要插入的数据
scanf("%d",&x); //若输入9999则创建空表
while(x != 9999)
{
p = (LNode *)malloc(sizeof(LNode));//创建一个新节点
p->data = x; //把元素放进数据域中
p->next = L->next; //指针域指向头节点指向的数据
L->next = p; //把头节点的指针指向新节点地址
printf("输入插入值(输入9999表示结束插入):\n");
scanf("%d",&x);
}
return L;
}
不带头节点,使用头插法建立新链表
/*不带头节点,建立新链表,头插法*/
LinkList UHeader_insert(LinkList &L)
{
LNode *p; int x;
printf("输入插入值(输入9999表示结束插入):\n");
scanf("%d",&x);
while(x != 9999)
{
p = (LNode *)malloc(sizeof(LNode)); //创建一个新节点
p->data = x; //把数据装入新节点数据域
p->next = L; //新节点指针域指向头指针指的数据地址
L = p; //头指针指向新节点(保持头指针一直指向头部)
printf("输入插入值(输入9999表示结束插入):\n");
scanf("%d",&x);
}
return L;
}
尾插法建立单链表
尾插法思想:
带头结点:
把新节点插在尾部。
定义一个尾指针,尾指针指向头节点,插入新节点,把最后一个节点指针域指向新节点,再让尾指针指向新节点,使尾指针始终指向尾部。
不带头结点:
尾指针指向头指针,头指针指向新节点,尾指针也指向这个新节点,也就是链表的第一个节点,再后面插入其他节点,让尾指针始终指向最后一个节点,这里操作和带头节点尾插法操作一样。
带头节点,使用尾插法建立链表
LinkList Tail_insert(LinkList &L)
{
LNode *p,*r; //r为尾指针
int x;
L = (LinkList)malloc(sizeof(LNode)); //创建一个新节点
L->next = NULL; //指针域为空
r = L; //尾指针指向头节点
printf("输入插入值:\n");
scanf("%d",&x);
while(x != 9999)
{
p = (LNode *)malloc(sizeof(LNode));//创建一个新节点
p->data = x; //把数据装入新节点数据域
r->next = p; //尾指针指针域指向新节点
r = p; //尾指针指向新节点(保持尾指针一直在最后一个节点)
printf("输入插入值(输入9999表示结束插入):\n");
scanf("%d",&x);
}
r->next = NULL; //将尾指针指向节点中指针域置空
return L;
}
不带头节点,使用尾插法建立链表
/*******不带头节点,尾插法建立新链表*****************/
LinkList UTail_insert(LinkList &L)
{
LNode *p,*r; //r为尾指针
int x;
r = L;
printf("输入插入值:\n");
scanf("%d",&x);
while(x != 9999)
{
p = (LNode *)malloc(sizeof(LNode));//创建一个新节点
p->data = x; //数据域存入数据
p->next = NULL; //指针域初始化为空
if(L == NULL) //链表为空时
{
L = p; //头节点指向新节点
r = L; //尾指针指向头节点
}
else
{
r->next = p;
r = p;//保持尾指针始终指向尾部
}
printf("输入插入值(输入9999表示结束插入):\n");
scanf("%d",&x);
}
r->next = NULL;
printf("带头节点,使用尾插法建立链表结束!\n");
return L;
}
#查找操作
按序号查找结点值
按序号查找思想
带头结点:
- 判断给的序号是否为零,为零返回头节点。不为零从头结点的后继节点开始标记。
- 判断节点是否为空,节点不为空情况下,程序往下执行,查找对应序号的节点,返回该节点。若程序执行到节点为空,未找到对应序号的节点,说明查找的序号超出链表长度,序号不合法。返回为空。
不带头结点:
- 判断给的序号小于等于零,则序号不合法。
- 序号大于零就从第一个节点开始标记,节点不为空情况下,程序往下执行,查找对应序号的节点,返回该节点。若程序执行到节点为空,未找到对应序号的节点,说明查找的序号超出链表长度,序号不合法。返回为空。
带头节点代码如下
/*******按序号查找节点值************/
LNode *GetElem(LinkList L,int i) //带头节点
{
int j = 1;
LNode *p = L->next;//从头节点的下一个节点开始
if(i == 0)
return L; //i==0返回头节点
if(i < 1)
return NULL; //i无效返回NULL
while(p && j < i)
/*p不为空和j<i时继续循环,当其中一个不满足结束循环,
当是由p为空时结束循环,说明i值超过了链表长度 */
{
p = p->next;//p指向下一个节点
j++; //标记序列
}
return p; //返回节点
}
不带头节点的代码和带头节点的差异不大,就是从第一个节点开始,把LNode *p = L->next,改为LNode *p = L 即可。
按值查找表节点
按值查找节点思想:
带头结点:
从头结点后继节点开始查找,在节点不为空,节点数据域不是要查找的元素,继续往下一个节点查找。直到找到为止,返回找到的节点,若直到节点为空了,都没找到,则返回空。
不带头结点:从第一个节点开始查找,后面操作同带头结点的操作。
带头节点代码如下
LNode *GetElem_P(LinkList L,ElemType e) //带头节点
{
LNode *p = L->next;//从头节点下一个节点开始
while(p != NULL && p->data != e) //节点不为空和节点数据域不等于要找的元素循环继续
p = p->next;
return p; //找到后返回该节点指针,否则返回NULL
}
不带头节点的代码和带头节点的差异不大,就是从第一个节点开始,把LNode *p = L->next,改为LNode *p = L 即可。
#插入节点操作
后插(在指定节点后面插入新节点)
后插思想:
在指定节点的后面插入新节点
bool insert_later(LinkList &L,ElemType a,ElemType e)//后插(在某节点位置后面插入)
{
LNode *p,*q;
int temp;
q = (LNode *)malloc(sizeof(LNode));//创建一个新节点
q->data = e; //把要插入的元素放入新节点中
p = GetElem_P(L,a);
if(p != NULL) //判断查找节点是否存在
{
q->next = p->next;
p->next = q;
}
else
return 0; //不存在查找的节点返回0
return 1; //插入完成返回1
}
扩展
/**在第i个位置后面插入元素**/
void insert_locationH(LinkList &L,int i,ElemType e)//在第i个位置后面插入元素
{
LNode *p,*q,*s;
int temp;
q = (LNode *)malloc(sizeof(LNode));//创建一个新节点
q->data = e; //把要插入的元素放入新节点中
p = GetElem(L,i-1); //获取第i-1个位置节点 ,并使指针指向该节点
s = p->next; //使 s 指针指向第i个节点
q->next = p->next; //要插入的节点指针域指向i-1指向的下一个节点
p->next = q; //第i-1个节点指向插入节点
temp = s->data; //交换数据域
s->data = q->data;
q->data = temp;
}
上面代码也可不用这么多行,可以直接获取第i个节点,代码如下
void insert_locationH(LinkList &L,int i,ElemType e)//在第i个位置后面插入元素
{
LNode *p,*q;
int temp;
q = (LNode *)malloc(sizeof(LNode));//创建一个新节点
q->data = e; //把要插入的元素放入新节点中
p = GetElem(L,i); //获取第i个位置节点 ,并使指针指向该节点
q->next = p->next; //要插入的节点指针域指向i-1指向的下一个节点
p->next = q; //第i个节点指向插入节点
}
前插(在指定节点位置前面插入新节点)
前插思想:
在指定节点前面插入新节点
bool insert_pro(LinkList &L,ElemType a,ElemType e)//前插 (在某节点位置前面插入)
{
LNode *p,*q;
int temp;
q = (LNode *)malloc(sizeof(LNode));//创建一个新节点
q->data = e; //把要插入的元素放入新节点中
p = GetElem_P(L,a);
if(p != NULL) //判断查找节点是否存在
{
q->next = p->next;
p->next = q;
temp = p->data; //交换数据域
p->data = q->data;
q->data = temp;
}
else
return 0; //不存在查找节点返回0
return 1; //插入完成返回1
}
在第i个节点之前插入新节点的代码与在第i个位置插入节点代码相同。
在第i个位置插入节点
在第i个位置插入节点思想:
找到第i-1个节点,对i-1个节点进行操作,要插入的节点指针域指向i-1指向的下一个节点,再使i-1个节点的指针域指向插入节点。
LinkList insert_location(LinkList &L,int i,ElemType e)//在第i个位置插入元素
{
LNode *p,*q;
q = (LNode *)malloc(sizeof(LNode));//创建一个新节点
q->data = e; //把要插入的元素放入新节点中
p = GetElem(L,i-1); //获取第i-1个位置节点 ,并使指针指向该节点
q->next = p->next; //要插入的节点指针域指向i-1指向的下一个节点
p->next = q; //第i-1个节点指向插入节点
}
#删除节点操作
按序列删除
按序列删除的思想:
1.判断i值是否合法,合法就找到被删除元素的前驱节点
2. 让前驱节点的指针域指向被删除节点的后继节点
3. 释放被删除的节点
//删除第i个节点
bool Delete_i(LinkList &L,int i)//(带头节点)
{
LNode *p,*q;
int k;
k = Lenght(L);
if(i > k && i < 1) //判断i值是否合法
return 0;
p = GetElem(L,i-1); //调用按序列查找函数,找到第i个节点的上一个节点并使p指向该节点
q = p->next; // q指向p的下一个节点,也就是要删除的节点
p->next = q->next; //被删除上一个节点指向被删除的下一个节点
free(q); //释放节点的存储空间
return 1;
按值删除
按值删除思想(1)
找到被删除节点
让被删除节点和后继互换数据域,互换之后要删除的节点就是这个后继节点。
让找到的节点指针域指向后继节点的下一个节点。
最后释放交换数据时候后继节点。
void Delete_P(LinkList &L,ElemType e)//(带头节点)
{
LNode *p,*q;
p = GetElem_P(L,e);
q = p->next;
p->data = p->next->data; //被删除节点与后继节点交换数据域
p->next = q->next; //互换之后的节点指针域指向后继节点的后继节点
free(q); //释放交换后的节点的存储空间
}
上述代码有个bug,就是当要删除的是最后一个节点,p->data = p->next->data;会出现下一个节点为空。【也就是p->next=NULL】,所以当要删除最后一个节点时要做额外处理。【本人太菜,想不到在不出现脏数据的情况下该怎么处理,于是才有下面第二种算法,上下两种算法时间复杂度相等】
按值删除思想(2)
在查找节点时,使用一个指针,使这个指针始终保持指向要被删除元素的前驱节点。
判断被删除节点指针域是否为空【其实就是判断是否是最后一个节点】。
不是最后一个节点,就让该节点的前驱节点的指针域指向被删除节点的后继节点。
是最后一个节点,就让被删除节点的前驱节点的指针域赋为空。
最后释放被删除节点。
void Delete_P(LinkList &L,ElemType e)//(带头节点)
{
LNode *q;
LNode *p = L->next;//从头节点下一个节点开始
while(p != NULL && p->data != e) //节点不为空和节点数据域不等于要找的元素循环继续
{
q = p; //使指针一直保持指向下一个节点的前驱节点
p = p->next;
}
if(p->next != NULL) //当下一个节点不为空时,执行下面操作
q->next = p->next; // 前驱节点指向被删除节点的后继节点
else
q->next = NULL; //当下一个节点为空时,对前驱指针指针域置空
free(p); //释放节点的存储空间
}
遍历链表
void PRINT_linklist1(LinkList L) //遍历单链表(带头节点)
{
LNode *p;
p = L;
while(p->next != NULL) //看下一节点是否为空,为空结束遍历
{
p = p->next; //从头节点的下一个节点开始遍历
printf("%d",p->data);
if(p->next != NULL) //(打印格式)下个节点不为空,就打印->
printf("->");
}
}
不带头节点的代码和带头节点的差异不大,就是从第一个节点开始,把LNode *p = L->next,改为LNode *p = L 即可。
求表长
int Lenght(LinkList L)
{
LNode *p;
int j = 0;
p = L->next;
while(p != NULL) //节点为空终止循环
{
p = p->next;//指向下一个节点
j++; //记录表长
}
return j;
}
综合代码
根据自己需求编写调试的代码,函数模块与上面对比略有改动。
代码中建立链表是带头节点的。
#include <stdio.h>
#include <malloc.h>
#include <stdlib.h>
typedef int ElemType;
typedef struct LNode{ //定义单链表结构体
ElemType data; //数据域
struct LNode *next; //指针域
}LNode,*LinkList;
/*带头节点建立新链表,头插法*/
LinkList Header_insert(LinkList &L)//带头节点
{
LNode *p; int x;
L = (LinkList)malloc(sizeof(LNode)); //创建头节点
L->next = NULL; //指针域为空
printf("输入插入值:\n"); //输入要插入的数据
scanf("%d",&x); //若输入9999则创建空表
while(x != 9999)
{
p = (LNode *)malloc(sizeof(LNode));//创建一个新节点
p->data = x; // 把元素放进数据域中
p->next = L->next; //指针域指向头节点指向的数据
L->next = p; //把头节点的指针指向新节点地址
printf("输入插入值(输入9999表示结束插入):\n");
scanf("%d",&x);
}
printf("带头节点,使用头插法建立链表结束!\n");
return L;
}
/********带头节点建立新链表,尾插法***********/
LinkList Tail_insert(LinkList &L)
{
LNode *p,*r; //r为尾指针
int x;
L = (LinkList)malloc(sizeof(LNode)); //创建一个新节点
L->next = NULL; //指针域为空
r = L; //尾指针指向头节点
printf("输入插入值:\n");
scanf("%d",&x);
while(x != 9999)
{
p = (LNode *)malloc(sizeof(LNode));//创建一个新节点
p->data = x; //把数据装入新节点数据域
r->next = p; //尾指针指针域指向新节点
r = p; //尾指针指向新节点(保持尾指针一直在最后一个节点)
printf("输入插入值(输入9999表示结束插入):\n");
scanf("%d",&x);
}
r->next = NULL; //将尾指针指向节点中指针域置空
printf("带头节点,使用尾插法建立链表结束!\n");
return L;
}
int Lenght(LinkList L)
{
LNode *p;
int j = 0;
p = L->next;
while(p != NULL)
{
p = p->next;
j++;
}
return j;
}
LNode *GetElem(LinkList L,int i) //带头节点
{
int j = 1;
LNode *p = L->next;//从头节点的下一个节点开始
if(i == 0)
return L; //i==0返回头节点
if(i < 1)
return NULL; //i无效返回NULL
while(p && j < i)
/*p不为空和j<i时继续循环,当其中一个不满足结束循环,
当是由p为空时结束循环,说明i值超过了链表长度 */
{
p = p->next;//p指向下一个节点
j++; //标记序列
}
return p; //返回节点
}
LNode * GetElem_P(LinkList L,ElemType e) //带头节点
{
LNode *p = L->next;//从头节点下一个节点开始
while(p != NULL && p->data != e) //节点不为空和节点数据域不等于要找的元素循环继续
p = p->next;
return p; //找到后返回该节点指针,否则返回NULL
}
//删除第i个节点
bool Delete_i(LinkList &L,int i)//(带头节点)
{
LNode *p,*q;
int k;
k = Lenght(L);
if(i > k && i < 1) //判断i值是否合法
return 0;
p = GetElem(L,i-1); //调用按序列查找函数,找到第i个节点的上一个节点并使p指向该节点
q = p->next; // q指向p的下一个节点,也就是要删除的节点
p->next = q->next; //被删除上一个节点指向被删除的下一个节点
free(q); //释放节点的存储空间
return 1;
}
bool Delete_P(LinkList &L,ElemType e)//(带头节点)
{
LNode *q;
LNode *p = L->next;//从头节点下一个节点开始
while(p != NULL && p->data != e) //节点不为空和节点数据域不等于要找的元素循环继续
{
q = p; //使指针一直保持指向下一个节点的前驱节点
p = p->next;
}
if(p == NULL)//判断删除值是否在链表中
return 0;
if(p->next != NULL) //当下一个节点不为空时,执行下面操作
q->next = p->next; // 前驱节点指向被删除节点的后继节点
else
q->next = NULL; //
free(p); //释放节点的存储空间
return 1;
}
bool insert_pro(LinkList &L,ElemType a,ElemType e)//前插 (在某节点位置前面插入)
{
LNode *p,*q;
int temp;
q = (LNode *)malloc(sizeof(LNode));//创建一个新节点
q->data = e; //把要插入的元素放入新节点中
p = GetElem_P(L,a);
if(p != NULL)
{
q->next = p->next;
p->next = q;
temp = p->data; //交换数据域
p->data = q->data;
q->data = temp;
}
else
return 0;
return 1;
}
bool insert_later(LinkList &L,ElemType a,ElemType e)//后插(在某节点位置后面插入)
{
LNode *p,*q;
int temp;
q = (LNode *)malloc(sizeof(LNode));//创建一个新节点
q->data = e; //把要插入的元素放入新节点中
p = GetElem_P(L,a);
if(p != NULL)
{
q->next = p->next;
p->next = q;
}
else
return 0;
return 1;
}
void insert_locationH(LinkList &L,int i,ElemType e)//在第i个位置后面插入元素
{
LNode *p,*q;
q = (LNode *)malloc(sizeof(LNode));//创建一个新节点
q->data = e; //把要插入的元素放入新节点中
p = GetElem(L,i); //获取第i个位置节点 ,并使指针指向该节点
q->next = p->next; //要插入的节点指针域指向i-1指向的下一个节点
p->next = q; //第i个节点指向插入节点
}
bool insert_location(LinkList &L,int i,ElemType e)//在第i个位置插入元素
{
LNode *p,*q;
q = (LNode *)malloc(sizeof(LNode));//创建一个新节点
q->data = e; //把要插入的元素放入新节点中
p = GetElem(L,i-1); //获取第i-1个位置节点 ,并使指针指向该节点
if(p == NULL) //i值不合法返回空,当i值不和法返回0
return 0;
q->next = p->next; //要插入的节点指针域指向i-1指向的下一个节点
p->next = q; //第i-1个节点指向插入节点
return 1;
}
void PRINT_linklist1(LinkList L) //遍历单链表(带头节点)
{
LNode *p;
p = L;
while(p->next != NULL) //看下一节点是否为空,为空结束遍历
{
p = p->next; //从头节点的下一个节点开始遍历
printf("%d",p->data);
if(p->next != NULL) //(打印格式)下个节点不为空,就打印->
printf("->");
}
printf("\n");
}
int main()
{
LNode *H,*W;
int n,a,k,j,b;
int g = 1;
LNode *p;
Tail_insert(W);//尾插法建立W链表
Header_insert(H);//头插法建立H链表
PRINT_linklist1(W); //遍历建立好的链表
PRINT_linklist1(H);
printf("**********************选*择*操*作*****************************\n");
printf("1.按序号擦找操作 2.按值查找操作\n");
printf("3.按序号删除操作 4.按值删除操作\n");
printf("5.按序号插入操作 6.遍历列表操作\n");
printf("7.在某节点前面插入新节点操作 8.在某节点前面插入新节点操作\n");
printf("*************************************************************\n");
while(1)
{
printf("输入你想进行的操作(输入对应序号1-8):");
scanf("%d",&n);
if(n == 1) //1.按序号擦找操作
{
printf("你想对那个链表操作 1.W 2.H\n");
printf("输入序号(空格隔开)\n");
scanf("%d %d",&k,&a);
if(k == 1)
{
p = GetElem(W,a);
printf("在 W 链表中第%d个节点数据域数据为%d\n",a,p->data);
}
else
{
p = GetElem(H,a);
printf("在 H 链表中第%d个节点数据域数据为%d\n",a,p->data);
}
printf("是否继续对链表的操作(Y(1)/N(0))输入1或0:");
scanf("%d",&g);
if(g == 0)
break;
}
else if(n == 2) //2.按值查找操作
{
printf("你想对那个链表操作 1.W 2.H\n");
printf("输入查找值(空格隔开)\n");
scanf("%d %d",&k,&a);
if(k == 1)
{
p = GetElem_P(W,a);
if(p != NULL)
printf("W 链表中存在%d\n",p->data);
else
printf(" W 链表中不存在%d\n",a);
}
else
{
p = GetElem_P(W,a);
if(p != NULL)
printf("H 链表中存在%d\n",p->data);
else
printf("H 链表中不存在%d\n",a);
}
printf("是否继续对链表的操作(Y(1)/N(0))输入1或0:");
scanf("%d",&g);
if(g == 0)
break;
}
else if(n == 3)//3.按序号删除操作
{
printf("你想对那个链表操作 1.W 2.H\n");
printf("输入序号(空格隔开)\n");
scanf("%d %d",&k,&a);
if(k == 1)
{
j = Delete_i(W,a);
if(j == 0)
printf("删除失败\n");
else
printf("删除成功\n");
}
else
{
j = Delete_i(H,a);
if(j == 0)
printf("删除失败\n");
else
printf("删除成功\n");
}
printf("是否继续对链表的操作(Y(1)/N(0))输入1或0:");
scanf("%d",&g);
if(g == 0)
break;
}
else if(n == 4)//4.按值删除操作
{
printf("你想对那个链表操作 1.W 2.H\n");
printf("输入删除值(空格隔开)\n");
scanf("%d %d",&k,&a);
if(k == 1)
{
j = Delete_P(W,a);
if(j == 0)
printf("链表中不存在%d\n",a);
else
printf("删除成功\n");
}
else
{
j = Delete_P(H,a);
if(j == 0)
printf("链表中不存在%d\n",a);
else
printf("删除成功\n");
}
printf("是否继续对链表的操作(Y(1)/N(0))输入1或0:");
scanf("%d",&g);
if(g == 0)
break;
}
else if(n == 5)//5.按序号插入操作
{
printf("你想对那个链表操作 1.W 2.H\n");
printf("输入序号和要插入的值(空格隔开)\n");
scanf("%d %d %d",&k,&b,&a);
if(k == 1)
{
j = insert_location(W,b,a);
if(j == 0)
printf("插入失败\n");
else
printf("插入成功\n");
}
else
{
j = insert_location(H,b,a);
if(j == 0)
printf("插入失败\n");
else
printf("插入成功\n");
}
printf("是否继续对链表的操作(Y(1)/N(0))输入1或0:");
scanf("%d",&g);
if(g == 0)
break;
}
else if(n == 6)//6.遍历列表操作
{
printf("你想对那个链表操作 1.W 2.H\n");
scanf("%d",&k);
if(k == 1)
PRINT_linklist1(W);
else
PRINT_linklist1(H);
printf("是否继续对链表的操作(Y(1)/N(0))输入1或0:");
scanf("%d",&g);
if(g == 0)
break;
}
else if(n == 7)//7.在某节点前面插入新节点操作
{
printf("你想对那个链表操作 1.W 2.H\n");
printf("输入指值和被插入的值(空格隔开)\n");
scanf("%d %d %d",&k,&b,&a);
if(k == 1)
{
j = insert_pro(W,b,a);
if(j == 0)
printf("插入失败\n");
else
printf("插入成功\n");
}
else
{
j = insert_pro(H,b,a);
if(j == 0)
printf("插入失败\n");
else
printf("插入成功\n");
}
printf("是否继续对链表的操作(Y(1)/N(0))输入1或0:");
scanf("%d",&g);
if(g == 0)
break;
}
else if(n == 8) //8.在某节点后面插入新节点操作
{
printf("你想对那个链表操作 1.W 2.H\n");
printf("输入指值和被插入的值(空格隔开)\n");
scanf("%d %d %d",&k,&b,&a);
if(k == 1)
{
j = insert_later(W,b,a);
if(j == 0)
printf("插入失败\n");
else
printf("插入成功\n");
}
else
{
j = insert_later(H,b,a);
if(j == 0)
printf("插入失败\n");
else
printf("插入成功\n");
}
printf("是否继续对链表的操作(Y(1)/N(0))输入1或0:");
scanf("%d",&g);
if(g == 0)
break;
}
else
printf("请输入正确操作\n");
}
}