为什么ListPrint函数输出的结果是这个?
#include"stdio.h"
#include
#define ERROR 0
#define OK 1
typedef int ElemType;
typedef struct Node//结点类型定义
{
ElemType data;
struct Node * next;
}Node, * LinkList;//LinkList为结构指针类型
InitList (LinkList * L)//初始化单链表
{
*L=(LinkList)malloc(sizeof(Node));//建立头结点
(*L)->next=NULL;//建立空的单链表L
}
void CreateFromHead(LinkList L)//头插法逆序建表
{
Node * s;
char c;
int flag=1;
while(flag)//flag初值为1,当输入"$"时,置flag为0,建表结束
{
c=getchar();
if(c!='$')
{
s=(Node*)malloc(sizeof(Node));//建立新结点S
s->data=c;
s->next=L->next;//将S结点插入头结点
L->next=s;
}
else flag=0;
}
}
void CreateFromTail(LinkList L)//尾插法顺序建表
{
char c;
Node * r,* s;
int flag=1;
r=L;//r指针动态指向链表的当前表尾,以便于插入表尾,其初值指向头结点
while(flag)
{
c=getchar();
if(c!=flag)
{
s=(Node*)malloc(sizeof(Node));
s->data=c;
r->next=s;
r=s;
}
else
{
flag=0;
r->next=NULL;//将最后一个结点的next链域置为空,表示链表的结束
}
}
}
Node * Get(LinkList L,int i)//按序号查找
{
int j;
Node * p;
p=L->next;
if(i<=0) return NULL;
p=L;j=0;//从头结点开始扫描
while((p->next!=NULL)&&(jp=p->next;//扫描下一个结点
j++;//结点计数器
}
if(i==j) return p;//找到了第i个结点
else return NULL;//找不到,,i<=0或i>n
}
Node * Locate(LinkList L,ElemType key)//按值查找
{
Node * p;
p=L->next;//从表中第一个结点开始
while(p!=NULL)//当前表未查完
{
if(p->data!=key)
{
p=p->next;
}
else break; //找到结点值=key时退出循环
}
return p;
}
int ListLength(LinkList L)//求单链表的长度
{
int j;
Node * p;
p=L->next;
j=0;//存放单链表的长度
while(p!=NULL)
{
p=p->next;
j++;
}
return j; //j为求得的单链表长度
}
int InsList(LinkList L,int i,ElemType e)//单链表插入操作
{
Node * pre,* s;
int k;
if(i<=0) return ERROR;
pre=L;k=0;//从头结点开始,查找第i-1个结点
while(pre!=NULL&&k1)//表未查完且未查到第i-1个时重复,找到pre指向第i-1个
{
pre=pre->next;
k=k+1;
}
if(pre==NULL)//pre为空,表已找完,但是未数到i-1个,说明插入位置不合理
{
printf("插入位置不合理!");
return ERROR;
}
s=(Node *)malloc(sizeof(Node));//申请新节点s
s->data=e;//值e置入s的数据域
s->next=pre->next;//修改指针,完成插入操作
pre->next=s;
return OK;
}
int DelList(LinkList L,int i,ElemType *e)//单链表的删除操作
{
Node * pre,* r;
int k;
pre=L;k=0;
while(pre->next!=NULL&&k1)//寻找被删除结点i的前驱i-1使p指向它
{
pre=pre->next;
k=k+1;
}
if(pre->next==NULL)//没有找到合法的前驱位置
{
printf("删除结点的位置i不合理!");
return ERROR;
}
r=pre->next;
pre->next=r->next;//修改指针,删除结点r
*e=r->data;
free(r);//释放被删除的结点所占的内存空间
return OK;
}
LinkList MergeLinkList(LinkList LA,LinkList LB)//合并两个有序的单链表
{ //建议用尾插法来顺序建表
Node * pa,* pb,*r;
LinkList LC;//将LC初始为空表
pa=LA->next;//pa指向LA表中的第一个结点
pb=LB->next;
LC=LA;
LC->next=NULL;r=LC;
while(pa!=NULL&&pa!=NULL)//两表均未处理完,优先选择较小值结点插入LC
{
if(pa->data<=pb->data)
{
r->next=pa;
r=pa;
pa=pa->next;
}
else
{
r->next=pb;
r=pb;
pb=pb->next;
}
}
if(pa) r->next=pa;//若仅LA表未完
else r->next=pb;//否则
free(LB);
return (LC);
}
void ListPrint(Node *L)
{
Node *p=L->next;
while (p->next != NULL)
{
printf("%d ", p->next->data);
p = p->next;
}
}
int main()
{
LinkList L1,L2;
InitList(&L1);InitList(&L2);
int choose,i;
int *e;
for(i=0;i<9;i++)
{
printf("*********************************************\n");
printf("* 菜单 *\n");
printf("* 1:头插逆序建表 2:尾插顺序建表 *\n");
printf("* 3:单链表插入 4:单链表删除 *\n");
printf("* 5:按序号查找 6:按值查找 *\n");
printf("* 7:求单链表长 8:合并有序链表 *\n");
printf("* 7:单链表逆置 8:输出单链表 *\n");
printf("*********************************************\n");
printf("输入想要进行操作的序号:");
scanf("%d",&choose);
if(choose==1)
{
printf("头插法逆序建表L1(输入$结束):");
printf("\n");
CreateFromHead(L1);
printf("当前单链表L1各元素为:");
ListPrint(L1);
printf("\n");
printf("头插法逆序建表L2(输入$结束):");
CreateFromHead(L2);
printf("\n");
printf("当前单链表L2各元素为:");
ListPrint(L2);
}
if(choose==2)
{
printf("尾插法逆序建表L1(输入$结束):");
CreateFromTail(L1);
printf("当前单链表L1各元素为:");
ListPrint(L1);
printf("尾插法逆序建表L2(输入$结束):");
CreateFromTail(L2);
printf("当前单链表L2各元素为:");
ListPrint(L2);
}
if(choose=3)
{
}
}
}
首先你的链表元素是int类型,但你输入用getchar(),导致输入的1被当做数字字符'1'接收,存储到int型就是数字'1'的ASCII码了。
另外换行符也是字符啊,换行符的ASCII码是10,所以你最终输出的实际是输入的字符的ASCII码
getchar得到的是个字符,而你却按int打印,打印的不是ascii码吗
10是换行符的ascii码,你把换行符也当数据存进链表里了
参考GPT和自己的思路:
根据代码中ListPrint函数的实现,可以看出它实际上输出的是单链表中每个结点的下一个结点的数据元素。所以在输出之前,需要将指针p指向链表的第一个结点。而在链表的最后一个结点输出后,p会指向链表的空结点,条件p->next!=NULL不成立,就会跳出循环,所以输出结果中没有最后一个结点的数据元素。因此,可以将while循环的条件改为p!=NULL,即可输出链表的所有结点数据元素。
输入类型不对啊,还有
if(choose=3)
你这里应该是==