对单链表的操作 运行时报错

编写对带表头结点的单链表的操作代码如下

#define OK 1
typedef int ElemType;
typedef int Status;
typedef struct node{
    ElemType element;       //结点的数据域
    struct node *link;      //结点的指针域
}Node;
typedef struct headerList{
    Node *head;
    int n;                  //元素个数
}HeaderList;
void main()
{
    int i;
    int x;
    HeaderList list;
    Init(&list);           //初始化线性表
    for(i=0;i<9;i++)
        Insert(&list,i-1,i);    //线性表中插入新元素
    printf("the linklist is:");
    Output(&list);
    Delete(&list,0);
    printf("\nthe deleted linklist is:");
    Output(&list);
    Find(&list,0,&x);
    printf("\nthe value is %d:",x);
    Destroy(&list);            //撤销运算:释放存储空间,防止内存泄漏
}
Status Init(HeaderList *h)
{
    h->head=(Node*)malloc(sizeof(Node));     //生成表头结点
    if(!h->head)
        return ERROR;
    h->head->link=NULL;                      //设置单链表为空表
    h->n=0;
    return OK;
}
Status Insert(HeaderList *h,int i,ElemType x)
{
    Node *p,*q;
    int j;
    if(i<-1||i>h->n-1)
        return ERROR;
    p=h->head;
    for(j=0;j<=i;j++)
        p=p->link;
    q=(Node*)malloc(sizeof(Node));
    q->element=x;
    q->link=p->link;
    p->link=q;
    h->n++;
    return OK;
}
Status Output(HeaderList *h)
{
    Node *p;
    if(!h->n)               //判断线性表是否为空
        return ERROR;
    p=h->head;
    while(p)
        printf("%d",p->element);
        p=p->link;
}
Status Delete(HeaderList *h,int i)
{
    Node *p,*q;
    int j;
    if(!h->n)
        return ERROR;
    if(i<-1||i>h->n-1)
        return ERROR;
    q=h->head;
    for(j=0;j<i;j++)
        q=q->link;
    p=q->link;
    q->link=p->link;
    free(p);             //释放p所指结点即ai的存储空间
    h->n--;
    return OK;
}
Status Find(HeaderList *h,int i,ElemType *x)
{
    Node *p;
    int j;
    if(i<0||i>h->n-1)
        return ERROR;
    p=h->head;
    for(j=0;j<=i;j++)
        p=p->link;
    *x=p->element;
    return OK;
}
void Destroy(HeaderList *h)
{
    Node *p;
    while(h->head)
    {
        p=h->head->link;
        free(h->head);
        h->head=p;
    }
}


运行报错:

img

我觉得可能是程序从上到下运行进入main后未出来,没有扫描到函数的声明部分。就把main函数放到程序的最后,运行后就出现乱码了

是什么问题导致的呢?

首先,这个叫编译错误,不叫运行错误。

  1. C++是按文件从上到下来编译的,你把main函数中调用了Init等函数,但是这些函数是在main函数之后申明的,也就是说在调用Init的时候,还不知道Init是什么。修改方法是把main函数放到最后。
  2. 从Init函数看,第一个节点,即head本身是不保存元素的。并且没有初始化。但是输出的时候,有输出head的元素。所以输出的第一个值是随机值。
  3. 输出函数的while语句没有加括号,导致死循环:
Status Output(HeaderList* h)
{
    Node* p;
    if (!h->n)               //判断线性表是否为空
        return ERROR;
    p = h->head;
    while (p)
    {
        printf("%d ", p->element);
        p = p->link;   //之前这一句在while外面
    }
}

按照这个代码执行,输出结果为:

img

最关键的是弄清楚是哪个节点保存第一个元素。

修改处见注释,供参考:

#include <stdio.h>          //修改
#include <stdlib.h>         //修改  
#define OK 1                
#define ERROR 0             //修改
typedef int ElemType;
typedef int Status;
typedef struct node {
    ElemType element;       //结点的数据域
    struct node* link;      //结点的指针域
}Node;
typedef struct headerList {
    Node* head;
    int n;                  //元素个数
}HeaderList;

Status Init(HeaderList* h)
{
    h->head = (Node*)malloc(sizeof(Node));     //生成表头结点
    if (!h->head)
        return ERROR;
    h->head->link = NULL;                      //设置单链表为空表
    h->n = 0;
    return OK;
}
Status Insert(HeaderList* h, int i, ElemType x)
{
    Node* p, * q;
    int j;
    if (i < 1 || i > h->n + 1)  //if (i<-1 || i>h->n - 1) 修改
        return ERROR;
    p = h->head;
    for (j = 0; j < i - 1; j++)  //for (j = 0; j <= i; j++) 修改
        p = p->link;
    q = (Node*)malloc(sizeof(Node));
    q->element = x;
    q->link = p->link;
    p->link = q;
    h->n++;
    return OK;
}
Status Output(HeaderList* h)
{
    Node* p;
    if (!h->n)               //判断线性表是否为空
        return ERROR;
    p = h->head->link;      //修改
    while (p){             //修改
        printf("%d ", p->element);
        p = p->link;
    }                     //修改  
}
Status Delete(HeaderList* h, int i)
{
    Node* p, * q;
    int j;
    if (!h->n)
        return ERROR;
    if (i < 1 || i > h->n) //if (i<-1 || i>h->n - 1) 修改
        return ERROR;
    q = h->head;
    for (j = 0; j < i - 1; j++) //for (j = 0; j < i; j++) 修改
        q = q->link;
    p = q->link;
    q->link = p->link;
    free(p);           //释放p所指结点即ai的存储空间
    h->n--;
    return OK;
}
Status Find(HeaderList* h, int i, ElemType* x)
{
    Node* p;
    int j;
    if (i < 1 || i > h->n)  //if (i < 0 || i > h->n - 1) 修改
        return ERROR;
    p = h->head;
    for (j = 0; j < i; j++) //for (j = 0; j <= i; j++) 修改
        p = p->link;
      *x = p->element;
    return OK;
}
void Destroy(HeaderList* h)
{
    Node* p;
    while (h->head)
    {
        p = h->head->link;
        free(h->head);
        h->head = p;
    }
}
void main()   //修改
{
    int i;
    int x = -999; //修改
    HeaderList list;
    Init(&list);           //初始化线性表
    for (i = 0; i < 9; i++)
        Insert(&list, i + 1, i);  //Insert(&list, i - 1, i); //线性表中插入新元素 修改
    printf("the linklist is:\n");
    Output(&list);
    Delete(&list, 1);
    printf("\nthe deleted linklist is:\n");
    Output(&list);
    Find(&list, 1, &x);
    printf("\nthe value is:%d\n", x);
    Destroy(&list);            //撤销运算:释放存储空间,防止内存泄漏
}