兔子不恰胡萝卜 2022-03-16 21:51 采纳率: 75%
浏览 290
已结题

数据结构——链表,不带头结点的头插法和尾插法

我想知道不带头结点的头插法和不带头结点的尾插法错在哪里,以及main函数部分有没有错,再者就是整体还能不能优化(前面两个是最主要的问题)

(注释是听网课记下的,不知道对了没有,帮忙看一下)

#include <stdio.h>
#include <stdlib.h>
#include <malloc.h>

//单链表结构体
//->是箭头
typedef int ElemType;
typedef struct node //node是结点的意思
{
ElemType data;
struct node* next;//next指向结点本身
}LNode, * LinkList;

//头插入法:带头结点(输入数据与输出数据相反)

void CreLinkListHead(LinkList L, int n)
{
LNode* s;//等价于LinkList s
ElemType x;
int i;
printf("头插法--输入结点:\n");
for (i = n; i > 0; i--)
{
scanf_s("%d", &x);//从键盘输入结点x的值
s = (LNode*)malloc(sizeof(LNode));//生成一个s结点
s->data = x;//数据域
s->next = L->next;//s的指针域指向下一个结点L的地址编号
L->next = s;
}
}

//输出链表信息

void OutPut(LinkList L)
{
LNode* p;
p = L->next;
while (p != NULL)
{
printf("%d ", p->data);
p = p->next;
}
printf("\n");
}

//尾部插入法:带头结点(输入数据与输出数据相同)

void CreLinkListTail(LinkList L, int n)
{
LNode* s, * r;//r结点
ElemType x;
int i;
r = L;//r结点的初始化,首先指向链表L
printf("尾插法--输入结点:\n");
for (i = n; i > 0; i--)
{
scanf_s("%d", &x);
s = (LNode*)malloc(sizeof(LNode));
s->data = x;
//上面三条语句和头部插入法相同
r->next = s;//r的下一个结点是s
r = s;//r指向s
}
if (r != NULL)//r后没有结点
{
r->next = NULL;
}
}

//尾部插入法:不带头结点(输入数据与输出数据相同)

LNode* CreLinkListTailNo(int n)
{
LNode* s, * r;//r结点
LinkList L = NULL;
r = L;//r结点的初始化,首先指向链表L
ElemType x;
int i;
printf("输入结点:\n");
for (i = n; i > 0; i--)
{
scanf_s("%d", &x);
s = (LNode*)malloc(sizeof(LNode));
s->data = x;
if (L == NULL)//链表的第一个结点的处理
{
L = s;
r = s;
continue;
}
r->next = s;//r的下一个结点是s
r = s;//r指向s
}
if (r != NULL)//r后没有结点
{
r->next = NULL;
}
return L;
}

//头插入法:不带头结点(输入数据与输出数据相反)

LNode* CreLinkListNo(int n)
{
LinkList L = NULL;
LNode* s;//等价于LinkList s
ElemType x;
int i;
printf("输入结点:\n");
for (i = n; i > 0; i--)
{
scanf_s("%d", &x);//从键盘输入结点x的值
s = (LNode*)malloc(sizeof(LNode));//生成一个s结点
s->data = x;//数据域
s->next = L;//s的指针域指向下一个结点L的地址编号
L = s;
}
}

//单链表插入操作:第i个位置插入s结点

int InsertList(LinkList L, int i, ElemType x)//x为数据域
{
LNode* p, * s;
int j = 0;
p = L;//p指向L的头
while (p->next != NULL && j < i)//p结点的下一个结点不能为空
{
p = p->next;//p指向p的下个结点
j++;
}
if (p == NULL)//链表的末尾
{
printf("插入位置i不合理!");
return 0;
}
else
{
s = (LNode*)malloc(sizeof(LNode));
s->data = x;//s的数据域
s->next = p->next;//s指向下一个结点,p当前所指向结点的下一个
p->next = s;//p的下一个结点等于s
return 1;
}
}

//单链表删除操作:删除第i个结点(s是要删除的结点)

int DeleteList(LinkList L, int i)
{
LNode* p, * s;
int j = 0;
p = L;//p从L开始
while (p->next != NULL && j < i)
{
p = p->next;
j++;
}
if (p == NULL)
{
printf("删除位置不合理!");
return 0;
}
else
{
s = p->next;//s所指向的结点是p的下个结点
p->next = s->next;//等价于p->next=p->next->next
free(s);//在内存里释放掉s所指向结点的空间
return 1;
}
}

void main()
{
int n;//n个结点
printf("请在键盘中输入链表有几个结点:\n");
scanf_s("%d", &n);//输入n个结点

//带头结点
//LinkList L = (LinkList)malloc(sizeof(LNode));//空链表的创建
//L->next = NULL;//指针域为空
//
//不带头结点尾插法建立单链表L
//LinkList L = CreLinkListTailNo(n);
//printf("不带头结点尾插法--输出建立后的单链表:\n");
//OutPut(L); //输出建立后的单链表
//
//不带头结点头插法建立单链表L
LinkList L = CreLinkListNo(n);
printf("不带头结点头插法--输出建立后的单链表:\n");
OutPut(L); //输出建立后的单链表
//

//CreLinkListTail(L, n);//尾插入法建立单链表L
//printf("尾插法--输出建立后的单链表:\n");
//OutPut(L); //输出建立后的单链表

//CreLinkListHead(L, n);//头插法建立单链表L
//printf("头插法--输出建立后的单链表:\n");
//OutPut(L);//输出建立后的单链表

//DeleteList(L, 3);//删除第3个位置的元素
//printf("输出删除后的单链表:\n");
//OutPut(L);//输出删除成功后的单链表

//InsertList(L, 3, 100);//在第3个位置插入一个数据元素100
//printf("输出插入后的单链表:\n");
//OutPut(L);//输出插入成功后的单链表

}

  • 写回答

2条回答 默认 最新

  • qzjhjxj 2022-03-17 21:04
    关注

    没什么问题,修改处见注释,供参考:

    #include <stdio.h>
    #include <stdlib.h>
    #include <malloc.h>
    
    //单链表结构体
    //->是箭头
    typedef int ElemType;
    typedef struct node //node是结点的意思
    {
        ElemType data;
        struct node* next;//next指向结点本身
    }LNode, * LinkList;
    
    //头插入法:带头结点(输入数据与输出数据相反)
    void CreLinkListHead(LinkList L, int n)
    {
        LNode* s;//等价于LinkList s
        ElemType x;
        int i;
        printf("带头结点头插法--输入结点:\n");
        for (i = n; i > 0; i--)
        {
            scanf("%d", &x);//从键盘输入结点x的值
            s = (LNode*)malloc(sizeof(LNode));//生成一个s结点
            s->next = NULL;     //修改
            s->data = x;//数据域
            s->next = L->next;//s的指针域指向下一个结点L的地址编号
            L->next = s;
        }
    }
    
    //输出链表信息
    void OutPut(LinkList L)
    {
        LNode* p;
        p = L;    //p = L->next; 修改
        while (p != NULL)
        {
            printf("%d ", p->data);
            p = p->next;
        }
        printf("\n");
    }
    
    //尾部插入法:带头结点(输入数据与输出数据相同)
    void CreLinkListTail(LinkList L, int n)
    {
        LNode* s, * r;//r结点
        ElemType x;
        int i;
        r = L;//r结点的初始化,首先指向链表L
        printf("带头结点尾插法--输入结点:\n");
        for (i = n; i > 0; i--)
        {
            scanf("%d", &x);
            s = (LNode*)malloc(sizeof(LNode));
            s->next = NULL;//修改
            s->data = x;
            //上面三条语句和头部插入法相同
            r->next = s;//r的下一个结点是s
            r = s;//r指向s
        }
            //if (r != NULL)//r后没有结点 //修改
            //{
            //    r->next = NULL;
            //}
    }
    
    //尾部插入法:不带头结点(输入数据与输出数据相同)
    LNode* CreLinkListTailNo(int n)
    {
        LNode* s, * r;//r结点
        LinkList L = NULL;
        r = L;//r结点的初始化,首先指向链表L
        ElemType x;
        int i;
        printf("输入结点:\n");
        for (i = n; i > 0; i--)
        {
            scanf("%d", &x);
            s = (LNode*)malloc(sizeof(LNode));
            s->next = NULL;   //修改
            s->data = x;
            if (L == NULL)//链表的第一个结点的处理
            {
                L = s;
                //r = s;    //修改
                //continue; //修改
            }
            else            //修改
                r->next = s;//r的下一个结点是s
            r = s;//r指向s
        }
              //if (r != NULL)//r后没有结点//修改
              //{
              //    r->next = NULL;
              //}
        return L;
    }
    
    //头插入法:不带头结点(输入数据与输出数据相反)
    LNode* CreLinkListNo(int n)
    {
        LinkList L = NULL;
        LNode* s;//等价于LinkList s
        ElemType x;
        int i;
        printf("输入结点:\n");
        for (i = n; i > 0; i--)
        {
            scanf("%d", &x);//从键盘输入结点x的值
            s = (LNode*)malloc(sizeof(LNode));//生成一个s结点
            s->next = NULL;    //修改
            s->data = x;//数据域
            s->next = L;//s的指针域指向下一个结点L的地址编号
            L = s;
        }
        return L; //修改
    }
    
    //单链表插入操作:第i个位置插入s结点
    int InsertList(LinkList L, int i, ElemType x)//x为数据域
    {
        LNode* p, * s;
        int j = 0;
        p = L;//p指向L的头
        while (p->next != NULL && j < i)//p结点的下一个结点不能为空
        {
             p = p->next;//p指向p的下个结点
             j++;
        }
        if (p == NULL)//链表的末尾
        {
             printf("插入位置i不合理!");
             return 0;
        }
        else
        {
             s = (LNode*)malloc(sizeof(LNode));
             s->data = x;//s的数据域
             s->next = p->next;//s指向下一个结点,p当前所指向结点的下一个
             p->next = s;//p的下一个结点等于s
             return 1;
        }
    }
    
    //单链表删除操作:删除第i个结点(s是要删除的结点)
    int DeleteList(LinkList L, int i)
    {
        LNode* p, * s;
        int j = 0;
        p = L;//p从L开始
        while (p->next != NULL && j < i)
        {
             p = p->next;
             j++;
        }
        if (p == NULL)
        {
             printf("删除位置不合理!");
             return 0;
        }
        else
        {
             s = p->next;//s所指向的结点是p的下个结点
             p->next = s->next;//等价于p->next=p->next->next
             free(s);//在内存里释放掉s所指向结点的空间
             return 1;
        }
    }
    
    void main()
    {
        int n;//n个结点
        printf("请在键盘中输入链表有几个结点:\n");
        scanf("%d", &n);//输入n个结点
    
        //
        //不带头结点尾插法建立单链表L
        LinkList L1 = CreLinkListTailNo(n);
        printf("不带头结点尾插法--输出建立后的单链表:\n");
        OutPut(L1); //输出建立后的单链表
    //
        //不带头结点头插法建立单链表L
        LinkList L2 = CreLinkListNo(n);
        printf("不带头结点头插法--输出建立后的单链表:\n");
        OutPut(L2); //输出建立后的单链表
    //
     
        //带头结点
        LinkList L = (LinkList)malloc(sizeof(LNode));//空链表的创建
        L->next = NULL;//指针域为空
    
        CreLinkListTail(L, n);//尾插入法建立单链表L
        printf("尾插法--输出建立后的单链表:\n");
        OutPut(L->next); //OutPut(L);//输出建立后的单链表 //修改
    
        LinkList LL = (LinkList)malloc(sizeof(LNode));//空链表的创建
        LL->next = NULL;//指针域为空
    
        CreLinkListHead(LL, n);//头插法建立单链表L
        printf("头插法--输出建立后的单链表:\n");
        OutPut(LL->next);//OutPut(L);//输出建立后的单链表 //修改
    
        //DeleteList(L, 3);//删除第3个位置的元素
        //printf("输出删除后的单链表:\n");
        //OutPut(L->next);//OutPut(L);//输出删除成功后的单链表
    
        //InsertList(L, 3, 100);//在第3个位置插入一个数据元素100
        //printf("输出插入后的单链表:\n");
        //OutPut(L);//输出插入成功后的单链表
    }
    
    
    本回答被题主选为最佳回答 , 对您是否有帮助呢?
    评论 编辑记录
查看更多回答(1条)

报告相同问题?

问题事件

  • 系统已结题 3月26日
  • 已采纳回答 3月18日
  • 创建了问题 3月16日

悬赏问题

  • ¥15 这种微信登录授权 谁可以做啊
  • ¥15 请问我该如何添加自己的数据去运行蚁群算法代码
  • ¥20 用HslCommunication 连接欧姆龙 plc有时会连接失败。报异常为“未知错误”
  • ¥15 网络设备配置与管理这个该怎么弄
  • ¥20 机器学习能否像多层线性模型一样处理嵌套数据
  • ¥20 西门子S7-Graph,S7-300,梯形图
  • ¥50 用易语言http 访问不了网页
  • ¥50 safari浏览器fetch提交数据后数据丢失问题
  • ¥15 matlab不知道怎么改,求解答!!
  • ¥15 永磁直线电机的电流环pi调不出来