2 qin water qin_water 于 2016.04.07 18:27 提问

单链表的头插法和尾插法,用同一个方法求长度。。。。
 #include <stdio.h>
#include <stdlib.h>
#include <malloc.h>

//单链表结构
typedef int datatype;
typedef struct node
{
    datatype data;
    struct node *next;
}linklist;
linklist *head,*p;//指针类型说明

/*头插法建表
用头插法建成的链表中结点的次序和输入的顺序是相反的。
*/
linklist *CREATLISTF(){
char ch;//逐个输入字符,以'#'为结束符,返回单链表头指针
linklist * head,*s;
head=NULL;//链表开始为空
ch=getchar();//读入第一个结点的值
while(ch!='#')
{
    s=malloc(sizeof(linklist));//生成新的结点
    s->data=ch;
    s->next=head;
    head=s;//将新结点插入到表头上
    ch=getchar();//读入下一个结点的值
}
    return head;//返回表头指针
}

//计算不带头结点的单链表的长度,然后输出单链表
void Print(linklist *L)
{
 int num=0;
 linklist *p;
 p=L;
 while(p)
 {
  printf("%c ",p->data);
  p=p->next;
  num++;
 }
 printf("\nthe length is :%d\n",num);
}
//尾插法——返回表的头指针
linklist *CREATLISTR(){
    char ch;
    linklist * head,*s,*r;
    head=NULL;//置空链表
    r=NULL;//尾指针初值为空。
    ch=getchar();
    while(ch!='#'){
        s=malloc(sizeof(linklist));//生成新的结点
        s->data=ch;
        if (head==NULL)
            head=s;
        else
            r->next=s;

        r=s;
        ch=getchar();   
    }
    if(r!=NULL)
        r->next=NULL;
  return head;
}
//查找——按照序号查找


//主函数
int main(){
    linklist *f,*r ;
    //printf("head insert:\n");
    //f=CREATLISTF();//头插法建立单链表
    //Print(f);//打印链表和链表的长度
    printf("tail insert:\n");
    r=CREATLISTR();//尾插法
    Print(r);

}

=============调用头插法和尾插法,右边是输出结果============================
调用头插法和尾插法
==============只是调用尾插法,右边是输出结果==============================

只是调用尾插法

在主函数中先是调用头插法再调用尾插法。但是尾插法输出的长度多了一个。如果只是在调用尾插法,长度就正常输出了。这到底是什么原因??

5个回答

qq423399099
qq423399099   Ds   Rxr 2016.04.18 09:51
已采纳

楼主你到底有没有加fflush(stdin)啊
加在main函数调用头插法和尾插法之间

 #include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <math.h>
//单链表结构
typedef int datatype;
typedef struct node {
    datatype data;
    struct node *next;
} linklist;
linklist *head, *p; //指针类型说明

/*头插法建表
用头插法建成的链表中结点的次序和输入的顺序是相反的。
*/
linklist *CREATLISTF() {
    char ch; //逐个输入字符,以'#'为结束符,返回单链表头指针
    linklist * head, *s;
    head = NULL; //链表开始为空
    ch = getchar(); //读入第一个结点的值
    while (ch != '#') {
        s = (linklist *)malloc(sizeof(linklist)); //生成新的结点
        s->data = ch;
        s->next = head;
        head = s; //将新结点插入到表头上
        ch = getchar(); //读入下一个结点的值
    }
    return head; //返回表头指针
}

//计算不带头结点的单链表的长度,然后输出单链表
void Print(linklist *L) {
    int num = 0;
    linklist *p;
    p = L;
    while (p) {
        printf("%c ", p->data);
        p = p->next;
        num++;
    }
    printf("\nthe length is :%d\n", num);
}
//尾插法——返回表的头指针
linklist *CREATLISTR() {
    char ch;
    linklist * head, *s, *r;
    head = NULL; //置空链表
    r = NULL; //尾指针初值为空。
    ch = getchar();
    while (ch != '#') {
        s = (linklist *)malloc(sizeof(linklist)); //生成新的结点
        s->data = ch;
        if (head == NULL)
            head = s;
        else
            r->next = s;

        r = s;
        ch = getchar();
    }
    if (r != NULL)
        r->next = NULL;
    return head;
}
//查找——按照序号查找

//主函数
int main() {
    linklist *f, *r;
    printf("head insert:\n");
    f=CREATLISTF();//头插法建立单链表
    Print(f);//打印链表和链表的长度
    fflush(stdin);
    printf("tail insert:\n");
    r = CREATLISTR(); //尾插法
    Print(r);

}

图片说明

CSDNXIAON
CSDNXIAON   2016.04.07 18:32

单链表尾插法与头插法
单链表的头插法与尾插法
头插法和尾插法创建单链表
----------------------同志你好,我是CSDN问答机器人小N,奉组织之命为你提供参考答案,编程尚未成功,同志仍需努力!

qq423399099
qq423399099   Ds   Rxr 2016.04.07 19:30

因为先调用完头插法(楼主是以#来判断读入结束的,那么就导致最后输入缓冲区里会遗留一个回车符)
再调用尾插法的时候,首先插入的节点就是\n,所以楼主打印的时候没有发现吗,多了一个空行和一个空格
(所以第二种,直接调用尾插法是正确的,不存在这个遗留的回车)
所以在两者之间加一个fflush(stdin);或者getchar()清楚掉回车符就好了

qin_water
qin_water 回复小灸舞: 对不起,我把这件事给忘了,真是抱歉。代码我贴出来了,请你帮帮修改,谢谢啦。
一年多之前 回复
qq423399099
qq423399099 回复昵称是水果: 我这里可以的啊。。。楼主再贴一下代码
一年多之前 回复
qin_water
qin_water 我有发现空行和空格,但是不知道是怎么产生的,现在知道了。在调用头插法和尾插法之间插入你说的方法,但是还是不行。
一年多之前 回复
qin_water
qin_water   2016.04.18 09:26

#include
#include
#include

//单链表结构
typedef int datatype;
typedef struct node {
datatype data;
struct node *next;
} linklist;
linklist *head, *p; //指针类型说明

/*头插法建表
用头插法建成的链表中结点的次序和输入的顺序是相反的。
*/
linklist *CREATLISTF() {
char ch; //逐个输入字符,以'#'为结束符,返回单链表头指针
linklist * head, *s;
head = NULL; //链表开始为空
ch = getchar(); //读入第一个结点的值
while (ch != '#') {
s = malloc(sizeof(linklist)); //生成新的结点
s->data = ch;
s->next = head;
head = s; //将新结点插入到表头上
ch = getchar(); //读入下一个结点的值
}
return head; //返回表头指针
}

//计算不带头结点的单链表的长度,然后输出单链表
void Print(linklist *L) {
int num = 0;
linklist *p;
p = L;
while (p) {
printf("%c ", p->data);
p = p->next;
num++;
}
printf("\nthe length is :%d\n", num);
}
//尾插法——返回表的头指针
linklist *CREATLISTR() {
char ch;
linklist * head, *s, *r;
head = NULL; //置空链表
r = NULL; //尾指针初值为空。
ch = getchar();
while (ch != '#') {
s = malloc(sizeof(linklist)); //生成新的结点
s->data = ch;
if (head == NULL)
head = s;
else
r->next = s;

    r = s;
    ch = getchar();
}
if (r != NULL)
    r->next = NULL;
return head;

}
//查找——按照序号查找

//主函数
int main() {
linklist *f, *r;
printf("head insert:\n");
f=CREATLISTF();//头插法建立单链表
Print(f);//打印链表和链表的长度
printf("tail insert:\n");
r = CREATLISTR(); //尾插法
Print(r);

}


qin_water
qin_water   2016.04.18 14:37

我之前真的有加,然后为了给你一个完整的代码,我又去掉了。我也不知道为什么我加的时候不行,现在 getchar()和fflush(stdin);都可以。。。
都是我的问题,多谢你如此耐心的解答,谢谢你~~~

Csdn user default icon
上传中...
上传图片
插入图片
准确详细的回答,更有利于被提问者采纳,从而获得C币。复制、灌水、广告等回答会被删除,是时候展现真正的技术了!