数据结构学习【线性表 链式结构 C++】单链表实现

数据结构学习【线性表 链式结构 C++】

最近在重新学习数据结构并打算实现部分代码,仅以此系列记录一下对应的代码实现。

本次实现的是线性表的链式存储结构——单链表。
默认采用头结点。

头结点和头指针区别

不管带不带头结点,头指针始终指向链表的第一个结点,而头结点是带头结点的链表中的第一个结点,通常不存储任何信息。(可以存储链表长度)
引入头结点的两个好处
1.由于第一个数据结点的位置被存放在头结点的指针域中,因此在链表的第一个位置上的操作和其他位置上的操作一致,无须进行特殊操作。
2.无论链表是否为空,其头指针始终指向头结点的非空指针,因此空表非空表的处理也得到了统一,

代码部分

#include <iostream>
using namespace std;
// 代码默认带头结点
// ADT
// InitList(&L); //初始化表
// List_HeadInsert(&L);//头插法建立单链表
// List_TailInsert(&L);//尾插法建立单链表
// DestroyList(&L);//销毁表

// ListInsert(&L,i,e);//在位序i插入元素e
    // InsertNextNode(*p,e);//在p节点之后插入元素e
    // InsertPriorNode(*p,e);//在p节点之前插入元素e
// ListDelete(&L,i,&e);//删除位序i的元素,并返回
    // DeleteNode(*p,&e);//删除指定节点
// GetElem(L,i);//按位查找,返回第i位元素的值
// LocateElem(L,e);//按值查找,返回值为e的元素的位序

// IsEmpty(L);//判断线性表是否为空
// PrintList(L);//顺序输出线性表

typedef struct LinkNode
{
    
    
    int data;
    LinkNode *next;
}LNode,*LinkList;

//初始化表
bool InitList(LinkList &L){
    
    
    L=(LNode*)malloc(sizeof(LNode));
    if(L==nullptr)//假设内存不足,返回false
        return false;
    L->next=nullptr;
    return true;
}
//头插法建立单链表
bool List_HeadInsert(LinkList &L){
    
    
    LNode*s;
    int x;
    if(InitList(L)){
    
    
        scanf("%d",&x);//读取数字
        while(x!=666){
    
    //输入数字为666即退出
            s=(LNode*)malloc(sizeof(LNode));
            s->data=x;
            s->next=L->next;
            L->next=s;
            scanf("%d",&x);//读取数字
        }
        return true;
    }else{
    
    
        return false;//创建失败
    }
}
//尾插法建立单链表
bool List_TailInsert(LinkList &L){
    
    
    LNode*s,*t;//这里s用作创建新节点,t始终指向尾结点
    int x;
    if(InitList(L)){
    
    
        t=L;
        scanf("%d",&x);//读取数字
        while(x!=666){
    
    //输入数字为666即退出
            s=(LNode*)malloc(sizeof(LNode));
            s->data=x;
            s->next=nullptr;
            t->next=s;
            t=s;
            scanf("%d",&x);//读取数字
        }
        return true;
    }else{
    
    
        return false;//创建失败
    }
}
//销毁表
void DestroyList(LinkList &L){
    
    
    LNode* p;
    while(L){
    
    
        p=L;
        L=L->next;
        free(p);
    }
}
//在p节点之后插入元素e
bool InsertNextNode(LNode *p,int e){
    
    
    if(p==nullptr)      //如果p为空
        return false;
    LNode *temp=(LNode*)malloc(sizeof(LNode));
    if(temp==nullptr)   //内存分配不足
        return false;
    temp->data=e;
    temp->next=p->next;
    p->next=temp;
    return true;
}
//在p节点之前插入元素e
// InsertPriorNode(*p,e);

//按位查找,返回第i位元素的节点地址
LNode* GetElem(LinkList L,int i){
    
    
    if(i<0)
        return nullptr;
    LNode *p;
    int j=0;
    p=L;
    while(p!=nullptr && j<i){
    
    
        p=p->next;
        j++;
    }
    return p;

}
//按值查找,返回值为e的元素的位
LNode* LocateElem(LinkList L,int e){
    
    
    LNode* tmp=L->next;//略过头结点
    while (tmp!=nullptr&&tmp->data!=e)
        tmp=tmp->next;
    return tmp;//tmp不为null代表找到了节点
}

//在位序i插入元素e
bool ListInsert(LinkList &L,int i,int e){
    
    
    LNode* p=GetElem(L,i-1);//找到前一位节点
    return InsertNextNode(p,e);
}
//删除位序i的元素,并返回
bool ListDelete(LinkList &L,int i,int &e){
    
    
    LNode* p=GetElem(L,i-1);//找到前一位节点
    LNode* q=p->next;//要删除的节点
    p->next=q->next;
    free(q);
    return true;
}


//判断线性表是否为空
bool IsEmpty(LinkList L){
    
    
    if(L->next==nullptr)
        return true;
    else
        return false;
}
//顺序输出线性表
void PrintList(LinkList L){
    
    
    if(!IsEmpty(L)){
    
    
        LinkNode* tmp=L;
        int i=0;//计数
        while(tmp->next!=nullptr){
    
    
            tmp=tmp->next;
            printf("第%3d 个元素值为 %d\n",++i,tmp->data);
        }
    }else{
    
    
        printf("线性表为空。\n");
    }
}

int main(){
    
    
    LinkList L;
    // List_HeadInsert(L);
    List_TailInsert(L);//创建链表
    PrintList(L);

    ListInsert(L,2,100);//在第二位插入100
    printf("\n");
    PrintList(L);

    int deleteElem;
    ListDelete(L,1,deleteElem);//删除第一位元素
    printf("\n");
    PrintList(L);

    system("pause");
}

运行截图
在这里插入图片描述

猜你喜欢

转载自blog.csdn.net/toro180/article/details/122362146