C语言链表 插入一个值 导致链表最后一位消失怎么办?
比如链表中本身有(1,2,3) 插入99在第二位后 链表就变成了(1,99,3)
//Linear Table On On Link List Structure
#include
#include
#include
#define FAIL 1;
#define OK 0;
//程序中反复出现的H=H->next是因为H的首地址不存数据
typedef int ElemType; //数据元素类型定义
typedef int DataType;
typedef struct Node //线性表链式存储结构的定义
{
DataType data;
struct Node* next;
}Node,*LinkList;
Node LNode;
int *px;
int i=0,x=0;
LinkList H,T,OriginH;
LinkList p;
//注意:下面的链表都采用带头节点的结构
LinkList CreateLinkList(int n); //带n个节点的链表,返回链表的头指针
void PrintList(LinkList L);//以(a1,a2,...,an)格式输出链表 OK
void EmptyList(LinkList L); //把链表H清空(保留头结点)
int ListLength(LinkList L); //返回链表H的长度 OK
Node* GetData(Node *L, int i, DataType*px);//查找第i(1≤i≤n)个元素,查找成功返回OK并把元素放入*px,查找失败返回FAIL
Node* Locate(LinkList H, DataType x); //查找元素x的位置,找到返回指向该结点指针,否则返回NULL
int InsList(LinkList H, int i, DataType x);//在链表H的第i个位置上插入值为x的元素,成功返回TRUE,否则FALSE
int DelList(LinkList L,int i, ElemType*px); //删除表中第i(1≤i≤n)个元素,删除元素值放入*px;删除成功返回OK,否则FAIL
int main()
{
LinkList H; //定义一个链表指针
//生成菜单
char sel=' ';
while(sel!='0')
{
printf("------线性表(链式存储结构)演示系统-------\n");
printf(" 版本:1.0 作者:XXXXXX 日期:yyyy-mm-dd\n");
printf("------------------------------------------\n");
printf(" 1.创建线性表\n"); //已经实现
printf(" 2.查找元素位置\n");
printf(" 3.按位置查找元素\n");
printf(" 4.插入一个元素\n");
printf(" 5.删除一个元素\n");
printf(" 6.打印线性表\n"); //已经实现 OK
printf(" 7.打印线表长度\n"); //OK
printf(" 8.清空线性表\n");
printf(" 9.清空屏幕\n"); //已经实现
printf(" 0.退出系统\n"); //已经实现
printf("请输入选项[0-7]:");
sel=getch();
switch(sel)
{
case '1':
int n;
printf("创建线性表操作.\n");
printf("请输入你要创建线性表的长度:");
scanf("%d",&n);
H = CreateLinkList(n);
system("pause"); //按任意键继续
break;
case '2':
printf("查找元素操作.\n");
//...
system("pause"); //按任意键继续
break;
case '3':
printf("按位置查找元素操作.\n");
//...
system("pause"); //按任意键继续
break;
case '4':
printf("插入一个元素操作.\n");
printf("请输入所插入的位置与数据的值:");
scanf("%d %d",&i,&x);
InsList(H,i,x);
system("pause"); //按任意键继续
break;
case '5':
printf("删除一个元素操作.\n");
//...
system("pause"); //按任意键继续
break;
case '6':
printf("显示线性表操作.\n");
PrintList(H);
system("pause"); //按任意键继续
break;
case '7':
printf("显示线性表长度.\n");
printf("长度为:%d\n",ListLength(H));
system("pause"); //按任意键继续
break;
case '8':
printf("清空线性表操作.\n");
//...
system("pause"); //按任意键继续
break;
case '9':
system("cls");
break;
case '0':
printf("\n谢谢使用,再见!\n");
break;
default:
printf("您输入的选项不合法,请重新选择!\n");
}
}
return 0;
}
//创建带n个节点的链表,返回链表的头指针
LinkList CreateLinkList(int n)
{
H = (LinkList) malloc(sizeof(LNode)); //申请一个LNode节点,把H指向这个新申请的节点 void*
H->next = NULL; //(*H).next = NULL;
OriginH=H;//统计长度或显示链表会导致地址后移,OriginH存放原始H地址
T=H;
int i;
printf("请输入%d个整数:",n);
for(i=0;iint x;
scanf("%d",&x);
//申请节点p,放入x
p=(LinkList)malloc(sizeof(LNode));
p->data = x;
p->next = NULL;
//把p点接入T后面
T->next = p;
T=p;
}
return H;
}
int ListLength(LinkList L)//统计长度
{
H=H->next;
int cnt=0;
while(H!=NULL)
{H=H->next;
cnt++;
}
H=OriginH;
return cnt;
}
int InsList(LinkList H, int i, DataType x)//插入
{
int length=ListLength(H);
int j=1;
if(i>length||i<1)
{printf("超出范围,无法插入!\n");
return FAIL;
}
else
{H=H->next;
for(;j!=i;j++)
{H=H->next;//后传直至找到第i个位置
}
x=x+H->data;//交换 x与 x=x+Tmp1->data的值 可以少用一个变量
H->data=x-H->data;
x=x-H->data;
for(int k=i;k//交换x与H.data中的数据方便后移
{H=H->next;//插入数据后将每一位数字后移
x=x+H->data;
H->data=x-H->data;
x=x-H->data;
}
printf("插入成功!\n");
H=OriginH;
return OK;
}
}
void PrintList(LinkList L)//打印链表
{int flag=0;//默认为第一位
H=H->next;
printf("(");
while(H!=NULL)
{if(flag==0)
{printf("%d",H->data);
flag=1;
}
else printf(",%d",H->data);
H=H->next;
}
printf(")");
H=OriginH;//返回初始位置
}
修改完善如下,具体改动处见注释,供参考:
//Linear Table On On Link List Structure
#include<stdio.h>
#include<conio.h>
#include<stdlib.h>
#define FAIL 1 //; 修改
#define OK 0 //; 修改
//程序中反复出现的H=H->next是因为H的首地址不存数据
typedef int ElemType; //数据元素类型定义
typedef int DataType;
typedef struct Node //线性表链式存储结构的定义
{
DataType data;
struct Node* next;
}LNode, * LinkList; //修改
//Node LNode; 修改
//int* px; 修改
//int i = 0, x = 0; 修改
//LinkList H, T, OriginH; 修改
//LinkList p; 修改
//注意:下面的链表都采用带头节点的结构
LinkList CreateLinkList(int n); //带n个节点的链表,返回链表的头指针
void PrintList(LinkList L);//以(a1,a2,...,an)格式输出链表 OK
void EmptyList(LinkList L); //把链表H清空(保留头结点)
int ListLength(LinkList L); //返回链表H的长度 OK
Node* GetData(Node* L, int i, DataType* px);//查找第i(1≤i≤n)个元素,查找成功返回OK并把元素放入*px,查找失败返回FAIL
Node* Locate(LinkList H, DataType x); //查找元素x的位置,找到返回指向该结点指针,否则返回NULL
int InsList(LinkList H, int i, DataType x);//在链表H的第i个位置上插入值为x的元素,成功返回TRUE,否则FALSE
int DelList(LinkList L, int i, ElemType* px); //删除表中第i(1≤i≤n)个元素,删除元素值放入*px;删除成功返回OK,否则FAIL
int main()
{
LinkList H = NULL;//定义一个链表指针 修改
int i = 0, x = 0; //修改
//生成菜单
char sel = ' ';
while (sel != '0')
{
printf("------线性表(链式存储结构)演示系统-------\n");
printf(" 版本:1.0 作者:XXXXXX 日期:yyyy-mm-dd\n");
printf("------------------------------------------\n");
printf(" 1.创建线性表\n"); //已经实现
printf(" 2.查找元素位置\n");
printf(" 3.按位置查找元素\n");
printf(" 4.插入一个元素\n");
printf(" 5.删除一个元素\n");
printf(" 6.打印线性表\n"); //已经实现 OK
printf(" 7.打印线表长度\n"); //OK
printf(" 8.清空线性表\n");
printf(" 9.清空屏幕\n"); //已经实现
printf(" 0.退出系统\n"); //已经实现
printf("请输入选项[0-7]:");
sel = getch();
switch (sel)
{
case '1':
int n;
printf("创建线性表操作.\n");
printf("请输入你要创建线性表的长度:");
scanf("%d", &n);
H = CreateLinkList(n);
system("pause"); //按任意键继续
break;
case '2':
printf("查找元素操作.\n");
//...
system("pause"); //按任意键继续
break;
case '3':
printf("按位置查找元素操作.\n");
//...
system("pause"); //按任意键继续
break;
case '4':
printf("插入一个元素操作.\n");
printf("请输入所插入的位置与数据的值:");
scanf("%d %d", &i, &x);
InsList(H, i, x);
system("pause"); //按任意键继续
break;
case '5':
printf("删除一个元素操作.\n");
//...
system("pause"); //按任意键继续
break;
case '6':
printf("显示线性表操作.\n");
PrintList(H);
system("pause"); //按任意键继续
break;
case '7':
printf("显示线性表长度.\n");
printf("长度为:%d\n", ListLength(H));
system("pause"); //按任意键继续
break;
case '8':
printf("清空线性表操作.\n");
//...
system("pause"); //按任意键继续
break;
case '9':
system("cls");
break;
case '0':
printf("\n谢谢使用,再见!\n");
break;
default:
printf("您输入的选项不合法,请重新选择!\n");
}
}
return 0;
}
//创建带n个节点的链表,返回链表的头指针
LinkList CreateLinkList(int n)
{
LinkList H = (LinkList)malloc(sizeof(LNode)); //修改
//申请一个LNode节点,把H指向这个新申请的节点 void*
H->next = NULL; //(*H).next = NULL;
//OriginH = H;//统计长度或显示链表会导致地址后移,OriginH存放原始H地址 修改
LinkList T = H; //修改
int i;
printf("请输入%d个整数:", n);
for (i = 0; i < n; i++)
{
int x;
scanf("%d", &x);
//申请节点p,放入x
LNode *p = (LinkList)malloc(sizeof(LNode)); //修改
p->data = x;
p->next = NULL;
//把p点接入T后面
T->next = p;
T = p;
}
return H;
}
int ListLength(LinkList L)//统计长度
{
int cnt = 0;
if (!L || !L->next) //修改
return cnt;
LinkList H = L->next; //H = H->next; 修改
while (H != NULL)
{
H = H->next;
cnt++;
}
//H = OriginH; 修改
return cnt;
}
int InsList(LinkList H, int i, DataType x)//插入
{
int length = ListLength(H);
int j = 0; // j = 1; 修改
if (i > length || i < 1)
{
printf("超出范围,无法插入!\n");
return FAIL;
}
else
{
LinkList L = H, tmp = NULL; //修改
while (L && j < i - 1) {
L = L->next;
j++;
}
tmp = (LinkList)malloc(sizeof(LNode));
tmp->next = NULL;
tmp->data = x;
tmp->next = L->next;
L->next = tmp;
//H = H->next;
//for (; j != i; j++)
//{
// H = H->next;//后传直至找到第i个位置
//}
//x = x + H->data;//交换 x与 x=x+Tmp1->data的值 可以少用一个变量
//H->data = x - H->data;
//x = x - H->data;
//for (int k = i; k < length; k++)//交换x与H.data中的数据方便后移
//{
// H = H->next;//插入数据后将每一位数字后移
// x = x + H->data;
// H->data = x - H->data;
// x = x - H->data;
//}
printf("插入成功!\n");
//H = OriginH;
return OK;
}
}
void PrintList(LinkList L)//打印链表
{
int flag = 0;//默认为第一位
if (!L || !L->next) //修改
return;
LinkList H = L->next; //H = H->next; 修改
printf("(");
while (H != NULL)
{
if (flag == 0)
{
printf("%d", H->data);
flag = 1;
}
else
printf(",%d", H->data);
H = H->next;
}
printf(")");
//H = OriginH;//返回初始位置 修改
}
后来发现可以通过在中间插一个指针达成插入数据的目的,但是最后一位还是被吞了
不知道你这个问题是否已经解决, 如果还没有解决的话: