3.2.3 单链表的建立与释放

本文介绍了一个使用C语言实现的链表创建程序,包括节点结构定义、链表创建、打印及释放等功能。程序通过用户输入数据来构建链表,并演示了如何遍历和释放链表。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

代码如下:
注意点:本程序在VS2010下,114行"  Link Head = NULL// Node声明并初始化" 的Head必须初始化后才能作为参数传递给Create_List函数,但在GCC编译器下,可以不进行初始化,为了兼顾兼容,严谨性,最好事先初始化。
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
/***********************************************************/
// 程序名称:createList.cpp
// 程序目的:设计一个将输入的数据建立成链表的程序
// 程序来源:数据结构(C语言版) P-60
// 日期:2013-8-13 16:12:30
/***********************************************************/


#include <stdio.h>
#include <stdlib.h>
#define Max 10
struct List         // Node声明
{
    int Number;
    char Name[Max];
    struct List* Next;
};
typedef struct List Node;
typedef Node* Link;

/************************************************************************/
// 释放链表                             
/************************************************************************/

void Free_List(Link Head)
{
    Link Pointer;

    while (NULL != Head)
    {
        Pointer = Head;
        Head = Head->Next;  // 下一个节点
        free(Pointer);
    }

    return;
}

/************************************************************************/
// 输出链表数据
/************************************************************************/

void Print_List(Link Head)
{
    Link Pointer;
    Pointer = Head;
    while (NULL != Pointer)
    {
        printf("\n #####输出数据##### \n");
        printf("数据编号:%d\n", Pointer->Number);
        printf("数据名称:%s\n", Pointer->Name);
        Pointer = Pointer->Next;
    }
    return;
}

/************************************************************************/
// 建立链表
/************************************************************************/

Link Create_list(Link Head)
{
    int DataNum;        // 数据编号
    char DataName[Max]; // 数据名称
    Link New;           // 节点声明
    Link Pointer;
    int i;

    Head = (Link)malloc(sizeof(Node));  // 内存配置

    if (NULL == Head)
        printf("内存分配失败!!\n");
    else
    {
        DataNum = 1;            // 初始数据编号
        Head->Number = DataNum; // 首节点数据编号

        printf("请输入数据名称: ");
        scanf("%s", DataName);
        for (i = 0; i <= Max; i++)
            Head->Name[i] = DataName[i];
        Head->Next = NULL;

        Pointer = Head;     // Pointer设为首节点
        while (1)
        {
            DataNum++;      // 数据编号递增
            New = (Link)malloc(sizeof(Node));
            if (NULL != New)
            {
                printf("请输入数据名称: ");
                scanf("%s", DataName);
                if (DataName[0] == '0'// 输入0则结束输入
                        break;

                New->Number = DataNum;
                for (i = 0; i <= Max; i++)
                {
                    New->Name[i] = DataName[i];
                }
                New->Next = NULL;
            }
            else
                printf("内存分配失败!!\n");

            Pointer->Next = New;        // 新节点串接在原列表尾端
            Pointer = New;          // 列表尾端为新节点
        }
    }
    return Head;
}

/************************************************************************/
// 主程序                                                               
/************************************************************************/

int main(void)
{
    Link Head = NULL;               // Node声明并初始化
    Link New_List;
    New_List = Create_list(Head);   // 建立链表

    if (New_List != NULL)
    {
        Print_List(New_List);
        Free_List(New_List);
    }

    return 0;
}
生成结果:



任务二:单链表上的简单选择排序 一、 问题描述 设数据元素类型为整型,在单链表上实现简单选择排序算法。 二、 基本要求 (1) 非降序排序。 (2) 就地实施排序。 (3) 显示各趟排序结果。 (4) 分析算法的时间、空间复杂度。 (5) 创建单链表。 (6) 显示单链表,用于查看所创建的单链表排序结果的各趟结果。 (7) 单链表上的简单选择排序。 三、 问题分析 (1) 创建显示单链表。 创建显示单链表可以参考单链表验证程序或通过包含头文件(LinkList.h)方式直接使用。 (2单链表上的简单选择排序。 简单选择排序的算法思想:第i趟排序是把序列第i小的元素,放在第i个位序上。在单链表上实施简单选择排序需设置两个工作指针:p指向第i个元素,r指向第i小元素。 LinkList.h代码如下 template <class DT> struct LNode //链表结点 { DT data; //数据域,存储数据元素值 LNode *next; //指针域,指向下一个结点 }; //算法2.1 template <class DT> bool PriorElem_e(LNode<DT> *L, DT e, DT &pre_e) // 求值为e的元素前驱 { int k; k=LocateElem_e(L,e); // 1.获取e的位序k if(k>1) // 2.位序k大于1 { GetElem_i(L,k-1,pre_e); // 第k-1个元素为e的前驱 return true; } else // 3.元素e无前驱 return false; // 返回false } //【算法2.14】 创建空单链表 template <class DT> bool InitList(LNode<DT> *&L) { L=new LNode<DT>; // 1.创建头结点 if(!L) exit(1); // 2.创建失败,退出 L->next=NULL; // 3.创建成功 return true; // 返回true } //【算法2.15】 尾插法创建n的元素 template <class DT> bool CreateList_1(LNode<DT> *&L,int n) { int i; LNode<DT> *p,*s; p=L; //1.工作指针初始化,指向尾结点 cout<<"依次输入"<<n<<"个数据元素:"<<endl; for(i=1; i<=n;i++) // 2.按元素位序正序创建各结点 { s=new LNode<DT>; // 2.1 新建一个结点s if (!s) // 2.2 创建失败,返回false return false; cin>>s->data; // 2.3 输入结点值 s->next=p->next; // 2.4 s 链在表尾 p->next=s; p=s; // 2.5 工作指针指向 s } return true; // 3.创建成功,返回true } //【算法2.16】 头插法创建n个元素 template <class DT> bool CreateList_2(LNode<DT> *(&L),int n) { int i; LNode<DT> *s; cout<<"逆序输入"<<n<<"个数据元素:"<<endl; for(i=1; i<=n;i++) // 1.按元素位序逆序创建各结点 { s=new LNode<DT>; // 1.1 新建一个结点 s if (!s) // 1.2 创建失败,返回false return false; cin>>s->data; // 1.3 输入结点值 s->next=L->next; // 1.4 s 在头结点后 L->next=s; } return true; // 1.创建成功,返回true } //【算法2.17】 template <class DT> void DestroyList(LNode<DT> *(&L)) // 释放链表所占空间 { LNode<DT> *p; while(L) // 1. 表非空,从头结点开始,依次释放结点 { p=L; // 1.1 处理表头结点 L=L->next; // 1.2 头指针后移 delete p; // 1.3 释放表头结点所占内存 } L=NULL; // 2.头指针指向空 } //【算法2.18】 获取第i个元素 template<class DT> bool GetElem_i(LNode<DT> *L,int i, DT &e) { LNode<DT> *p; // 1.初始化 p=L->next; // 1.1 设置工作指针,从首结点开始数结点 int j=1; // 1.2 计数器初始化 while(p&&j<i) // 2.定位到第i个元素结点 { p=p->next;j++; } if(!p ||j>i ) // 3 未找到,返回false return false; else // 4. 找到 { e=p->data; // 获取第i个元素值 return true; // 返回true } } //【算法2.19】 查找值为e的元素位序 template<class DT> int LocateElem_e(LNode<DT> *L, DT e) { LNode<DT> *p; // 1.初始化从首元开始查找 p=L->next; // 1.1从首元开始查找 int j=1; // 1.2 计数器初值 while(p && p->data!=e) // 2.顺序查找 { p=p->next; // 2.1未找到指针后移 j++; // 2.2 计数器增1 } if(p==NULL) // 3. 判断是否找到 return 0; // 3.1末找到,返回0 else return j; // 3.2 找到,返回位序 } //【算法2.20】 插入第i个元素 template<class DT> bool InsertElem_i(LNode<DT> *&L,int i, DT e) { int j=0; LNode<DT> *p; // 1.初始化 p=L; // 工作指针初始化 while(p && j<i-1) // 2. 定位到插入点前驱 { p=p->next; j++; } if(!p||j>i-1) // 3.判断定位是否成功: return false; // 3.1 定位失败,不能插入 else // 3.2 定位成功 { LNode<DT> *s; s=new LNode<DT>; // 3.2.1建立新结点 s->data=e; // 3.2.2新结点赋值 s->next=p->next; // 3.2.3结点S链接到p结点之后 p->next=s; return true; // 3.2.4 插入成功,返回true } } //【算法2.21】 删除第i个元素 template<class DT> bool DeleElem_i(LNode<DT> *(&L),int i) { LNode<DT> *p,*q; //1.初始化:设置工作指针 p=L; //查找从头结点开始 int j=0; //计数器初始化 while(p->next && j<i-1) //2.p定位到删除点的前驱 { p=p->next; j++; } if(!p->next||j>i-1) //3.删除位置不合理,不能删除 return false; //返回false else //4.删除操作 { q=p->next; //4.1暂存删除结点位置 p->next=q->next; //4.2链表中摘除删除结点 delete q; return true; //4.3删除成功,返回true } } //【算法2.22】 修改第i个元素值 template<class DT> bool PutElem_i(LNode<DT> *(&L),int i, DT e) { LNode<DT> *p; // 1.初始化:设置工作指针 p=L->next; // 从首结点开始,数结点 int j=1; // 计数器初始化 while(p&&j<i) // 2.查找第i个元素结点 { p=p->next;j++; } if(!p||j>i) // 3.元素不存在,返回false return false; else // 4.定位成功 { p->data=e; // 修改元素值 return true; // 返回true } } // 释放链表所占空间 template<class DT> void ClearList(LNode<DT> *(&L)) { LNode<DT> *p; while(L->next) // 从首元结点开始,依次释放结点 { p=L->next; L->next=p->next; delete p; } cout<<endl<<"表已清空!"<<endl; } //【算法2.23】 测表长 template<class DT> int ListLength(LNode<DT> *L) { // 1.初始化 int len=0; // 1.1 结点计数器赋初值0 LNode<DT> *p; // 1.2设置工作指针 p=L; // 指向头结点 while(p->next) // 2.数结点个数。有后继结点, { len++;p=p->next; // 结点数增1,指针后移 } return len; // 3.返回表长 } // template<class DT> bool ListEmpty(LNode<DT> *L) //测表空 { if(L->next==NULL) return true; //空表,返回1 else return false; //不空,返回0 } //【算法2.24】 遍历表 template <class DT> void DispList(LNode<DT> *L) // 显示表内容 { LNode<DT> *p; // 1. 设置工作指针 p=L->next; // 从首元结点开始遍历 while(p) // 2.依次输出各结点值 { cout<<p->data<<"\t"; p=p->next; } cout<<endl; } 并采用下列代码 void SelectSort_L1(LNode<int> * &L) { if(L->next == NULL || L->next->next == NULL) { return; } p = L->next; while(p) { r = minNode(p); if(r != p) { e = p->data; p->data = r->data; r->data =e; } p = p->next; } }
最新发布
06-11
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值