首页 诗词 字典 板报 句子 名言 友答 励志 学校 网站地图
当前位置: 首页 > 教程频道 > 开发语言 > C语言 >

求教单链表有关问题.纠结一晚上了.

2013-08-04 
求教单链表问题...纠结一晚上了...这个程序是我看书之后自己编写的,因为刚刚接触,所以还有很多地方不明白。

求教单链表问题...纠结一晚上了...
这个程序是我看书之后自己编写的,因为刚刚接触,所以还有很多地方不明白。。。想请各位前辈帮我看一下哪里出错了。。我看了一晚上也没有找出来。。很纠结。。
#include<stdio.h>
#include<malloc.h>
#include<stdlib.h>
#include<conio.h>
#define OK 1
#define ERROR 0
typedef int datatype;
typedef struct
{
    datatype data;
    struct lnode *next;
}lnode,*linklist;

void createfromhead(linklist L,int n)
{

    lnode *p,*q;
    int i;
    L=(lnode*)malloc(sizeof(lnode));
    L->next=NULL;
    p=L;
    printf("\n\t依次输入元素:");
    for(i=1;i<=n;i++)
    {
        q=(lnode*)malloc(sizeof(lnode));
        scanf("%d",&(q->data));
        q->next=p->next;
        p->next=q;
        p=q;
    }
}

int insertlist(linklist L,int i,datatype e)
{

    lnode *p,*q;
    int j;
    j=0;
    p=L;
    while(j<i-1&&p)
    {
        p=p->next;
        j++;
    }
    if(!p||j>i-1) return ERROR;
    q=(lnode*)malloc(sizeof(lnode));
    q->data=e;
    q->next=p->next;
    p->next=q;
    return OK;
}

int deletelist(linklist L,int i,datatype *e)
{
    lnode *p,*q;
    int j=0;
    p=L;
    while(j<i-1&&p->next)
    {
        p=p->next;
        j++;
    }
    if(!(p->next)||j>i-1) return ERROR;
    q=p->next;
    p->next=q->next;
    free(q);
    return OK;
}

int locate(linklist L,datatype x)
{
    lnode *p;
    int i=1;


    p=L->next;
    while(p)
    {
        if(p->data==x)
            return i;
        else
        {
            p=p->next;
            i++;
        }
    }
    return OK;
}

int deleteall(linklist L)
{
    lnode *p,*q;
    p=L;
    q=L->next;
    while(q)
    {
        p->next=q->next;
        free(q);
        q=p->next;
    }
    return OK;
}

void printlist(linklist L)
{
    lnode *p;
    p=L->next;
    printf("\n\t单链表的元素为: ");
    while(p)
    {
        printf("%d ",p->data);
        p=p->next;
    }
}


void operate(linklist L)
{
    int i,e,x;
    int choose;
    while(1)
    {
        printf("\n\t");
        printf("\n\t--------------操作界面--------------");
        printf("\n\t1.插入 2.删除 3.查找 4.删除所有 0.退出");
        printf("\n\t输入你的选择:");
        scanf("%d",&choose);
        switch(choose)
        {
            case 1:
                {
                    printf("\n\t输入要插入元素的位置和数值:");
                    scanf("%d %d",&i,&e);
                    if(insertlist(L,i,e))


                        printlist(L);
                    else
                        printf("\n\t输入错误!");
                    break;
                }
            case 2:
                {
                    printf("\n\t输入要删除元素的位置:");
                    scanf("%d",&i);
                    if(deletelist(L,i,&e))
                        printlist(L);
                    else
                        printf("\n\t输入错误!");
                    break;
                }
            case 3:
                {
                    printf("\n\t输入想要查找的元素:");
                    scanf("%d",&x);
                    if(locate(L,x))
                    {
                        printf("\n\t该元素的位置是:");
                        printf("\n\t %d",locate(L,x));


                        break;
                    }
                }
            case 4:
                {
                    deleteall(L);
                    printf("\n\t删除后的链表:");
                    printlist(L);
                }
            case 0:
                {
                    exit(OK);
                    break;
                }
            default:
                printf("\t输入指令错误,请按规则输入\n\n");
    break;
        }
    }
}

int main(int argc, char** argv)
{
    int n;
    lnode *L;
    printf("\n\t输入创建链表元素的个数:");
    scanf("%d",&n);
    createfromhead(L,n);
    printf("\n\t链表创建成功!");
    printlist(L);
    printf("\n\t任意输入进入操作界面。");
    getch();
    system("cls");
    operate(L);
    return OK;
}




单链表


[解决办法]

引用:
Quote: 引用:

Quote: 引用:

Quote: 引用:

Quote: 引用:

Quote: 引用:

函数createfromhead(L,n)调用后,L实际并未初始化,未分配到申请的内存,即L指针指向的内存地址是非法的。因为函数参数的传递是“值传递”,传递给createfromhead函数的是L的一个副本。
修改方法:
  1.二级指针做参数
  2.引用传递
  3.在createfromhead函数里malloc头指针,返回该链表的头指针。

请问一下在调用createfromhead(L,n)之后,L为什么实际并未初始化...

要深刻理解C语言函数传递参数是“值传递”,在main函数里定义的L指针,比如&L=addr1,经函数createfromhead调用L,实际传递的是L的一个副本_L,&_L=addr2,addr1不等于addr2,但是L=_L,即指向的内存地址是一样的。createfromhead的malloc函数使_L指向的内存地址发生了变化,但main函数的L还是指向原来的地址。
不知道我说的你明白吗。


那么如果我把malloc用在main函数里面,是不是可以避免这种情况?


可以在main函数里面malloc,不过大部分是在初始化链表的函数里malloc,返回malloc申请的指针,在销毁链表的函数free申请的指针。
常用的方法:
  1.二级指针做参数
  2.在createfromhead函数里malloc头指针,返回该链表的头指针。


刚才想了一下用二级指针做参数,不知道想的对不对,求请前辈指教一下~
我在main函数里面用的lnode *L,定义L指针,但是在进行初始化,删除或者插入操作的时候,是改变L这个指针的值的,所以我们要在初始化,插入函数或者删除函数里用linklist *L来定义一个指向L指针的指针,所以要用二级指针来做参数。
可是在用malloc的时候,要*L=(LinkList)malloc(sizeof(Node)); (*L)->next=NULL;
我想问一下这个时候*L代表的是什么意思?是指向L指针的指针?那为什么会等于后面的东西呢。。
我刚刚接触数据结构,指针学的也不是很明白,希望前辈能赐教一下。。 


传二级指针的目的是希望改变一级指针指向的地址,正如传一级指针可以改变该指针指向的内容。
在主函数这样调用createfromhead(&L),声明如下createfromhead(LinkList *L)。具体的你可以在网上搜一下。

热点排行