王道数据结构实践代码----单链表的实现(C语言版)

王道数据结构实践代码----单链表的实现(C语言版)

前言

日期:2021年8月26日
书籍:王道2021年数据结构考研复习指导
代码内容:实现单链表的实现,包括初始化,插入新元素,删除新元素,输出,查询

代码难点

1.C语言的指针和C++的引用转换


指针我太阳你个**
简而言之,王道书上的单链表声明和初始化是以C++为模板的,C语言无法直接使用,需要做一定的转换,介于我指针学的也不是很好,就不说这中间的转换过程和原理了,日后有闲暇了再慢慢研究

2.头插法和尾插法的区别,带头指针和不带头指针的区别

引入头结点后,可以带来两个优点:
①由于第一个数据结点的位置被存放在头结点的指针域中,因此在链表的第一个位置上的操作和在表的其他位置上的操作一致,无须进行特殊处理。
②无论链表是否为空,其头指针都指向头结点的非空指针(空表中头结点的指针域为空)因此空表和非空表的处理也就得到了统一。
所以,没事儿写代码就把头指针带着吧

头插法vs尾插法
采用头插法建立单链表时,读入数据的顺序与生成的链表中的元素的顺序是相反的。
头插法建立单链表的算法虽然简单,但生成的链表中结点的次序和输入数据的顺序不一致。若希望两者次序一致,则可采用尾插法。该方法将新结点插入到当前链表的表尾,为此必须增加个尾指针r,使其始终指向当前链表的尾结点.

各功能代码

C语言自定义bool操作

//C语言自定义bool操作
#define bool char
#define false 0
#define true 1

单链表结构体定义

/*数据元素类型*/
typedef int ElemType;

/*单链表结构体定义*/
typedef struct LNode        //定义单链表结点类型
{
   
    ElemType data;          //每个结点存放一个数据元素
    struct LNode *next;     //指针指向下一节点
}LNode,*LinkList;

/*
    上面的代码等价于
    typedef struct Lnode Lnode;
    typedef struct Lnode * Linklist;
*/

//LinkList L; //声明一个指向单链表第一个结点的指针,这种方法代码可读性更强
/*
    上面的代码也可写成:
    LNode *L;
    //声明一个指向单链表第一个结点的指针,但这种方法可读性不强,
    //无法第一时间看出L是指向整个链表的头指针,还是仅仅是个新的结点
*/

链表初始化函数

LinkList ListInit()
{
   
    //[1]申请一块LinkList类型的存储空间给L
    LinkList L = (LinkList)malloc(sizeof(LinkList));
    //[2]设置L的指针域为空
    L->next = NULL;
    //返回L指针
    return L;
}

创建新结点函数

//创建新结点
LNode* createNote(int data)
{
   
    //[1]为新节点申请空间
    LNode* newNode = (LNode*)malloc(sizeof(LNode));
    //[2]如果内存满了,则分配失败,返回0
    if(newNode == NULL) 
    {
   
        printf("分配结点失败,请检查内存!");
        return NULL;
    }
    //[3]为新节点的数据域和指针域分别赋值
    newNode->data = data;
    newNode->next = NULL;
    //[4]返回新节点的指针
    return newNode;
}

头插法&尾插法

//头插法
bool ListHeadInsert(LinkList L,ElemType data)
{
   
    //[1]调用创建新节点函数,为其赋值
    LNode* newNode = createNote(data);
    //[2]先给新节点的指针域赋值(指向原来链表的第一个节点)
    newNode->next = L->next;
    //[3]再让头结点指向新结点
    L->next = newNode;
    //[4]返回true,表示插入成功
    return true;
}

//尾插法(不带尾指针的尾插法,因此每次插入新元素都需要遍历列表,所以时间复杂度为O(n))
bool ListTailInsert(LinkList L,ElemType data)
{
   
    //[1]申请新节点
    LNode* newNode = createNote(data);
    //[2]生成工具指针
    LNode* p = L->next;
    //[3]遍历链表,找到最后的元素,用工具指针指向它
    while (p->next != NULL)
    {
   
        p = p->next;
    }
    //[4]尾插入新节点
    newNode->next = NULL;
    p->next = newNode;
}

查询

//按序号查找节点值
LNode *GetElem(LinkList L,int i)
{
   
    //[1]设置一个变量计数
    int j = 1;
    //[2]设置待返回的结点p,开始指向第一个结点
    LNode *p = L->next;
    //[3]检查参数
    if(i == 0) {
   

你可能感兴趣的:(数据结构,数据结构,链表,c语言)