数据结构:静态链表和动态链表

链表的基本思想 

        

通过指针将数据连接起来

整个数据结构中,很重要的一点是,初始化和销毁对应,插入和删除对应,有malloc(new)有free(delete),一定要对应。  

插入的基本思想:

      

链表的各项操作,最关键的,其实就是找到被操作元素的上一个元素,插入位置的上一个元素,或者要删除元素的上一个元素,这都是非常关键的,同时也要注意, 

链表有个最大的特点,就是头指针所指向的位置,不放任何元素 

 

删除的基本思想 

      

 

静态链表和动态链表中,都是手动插入元素,而且编程人员是知道要插入数据的数据类型的,静态链表可操作性较差,动态链表比较灵活,但是二者总体上都无法完成封装,总归还是面对过程变成

关于链表更加具有适应性和更加详细的说明见:

 数据结构:单向链表:https://blog.csdn.net/qq_41605114/article/details/104396149

其中对各个部分的讲解比较详细,以下程序都比较简单,整个链表的基本思想也如上图所示。

 

静态链表:(在无指针的编程语言中实现链表)

大小固定,插入元素是固定的。一般会设置一个元素为用户自定义类型的数组,大小是固定的。

例如:

#define MAX 1000
typedef struct StaticList
{
    int data;存放数据
    int cur;//用下标来代替指针

}SL;
SL Test[MAX];

下面的程序显然没有这么做,只是在思想上重现了静态链表 

  

(图源:《大话数据结构》)

 

.h

//静态链表
struct LinkContentStatic
{
    int data;
    struct LinkContentStatic * next;
};

.cpp 

    LinkContentStatic node1 = {10,nullptr};
    LinkContentStatic node2 = {20,nullptr};
    LinkContentStatic node3 = {30,nullptr};
    LinkContentStatic node4 = {40,nullptr};
    LinkContentStatic node5 = {50,nullptr};
    LinkContentStatic node6 = {60,nullptr};

    node1.next = &node2;
    node2.next = &node3;
    node3.next = &node4;
    node4.next = &node5;
    node5.next = &node6;

    //如何遍历这个链表
    LinkContentStatic * PCurrent = &node1;
    while(PCurrent!=nullptr)
    {
        qDebug()<<"Item:"<<PCurrent->data;
        PCurrent = PCurrent->next;
    }

输出:

动态链表:

元素也是提前插入的,操作过程中也可以选择插入元素,删除元素等操作

链表有个最大的特点,就是头指针所指向的位置,不放任何元素 

.h

struct LinkNode
{
    int data;
    LinkNode * next;
};
//初始化
LinkNode * init_dynamic();
//在oldval后面插入一个newval
void InsertByValue_dynamic(LinkNode * header,int oldval,LinkNode * newval);
//删除val的链表
void remove_dynamic(LinkNode * header,int delValue);
//遍历
void Foreach_dynamic(LinkNode * header);
//销毁
void destroy_dynamic(LinkNode * header);
//清空
void clear_dynamic(LinkNode * header);
//大小
int size_dynamic(LinkNode * header);

.cpp

//初始化
LinkNode * init_dynamic()
{
    LinkNode * mydynamci = new LinkNode;//注意,在此处new了,那么就要在销毁的部分delete
    mydynamci->data = 0;
    mydynamci->next = nullptr;
    return mydynamci;
}
//在oldval的位置插入一个newval,old数据在new后面
void InsertByValue_dynamic(LinkNode * header,int oldval,LinkNode * newval)
{
    if(nullptr == header)
        return;
    LinkNode * pfind= header;
    LinkNode * PCurrent = header;
    int place = 0;
    bool flag = true;//找到元素的标志位
    while (pfind->next!=nullptr)
    {
        if(oldval == pfind->next->data)
        {
            flag = false;
            break;
        }
        pfind = pfind->next;
        place++;//old 的 前一个元素的位置
    }
    //如果找到了要找的元素,则进行插入操作
    if(flag == false)
    {
        for(int i = 0;i<place;++i)
        {
            PCurrent = PCurrent->next;
        }
        LinkNode * temp= PCurrent->next;//old所在的位置
        PCurrent->next = newval;
        newval->next = temp;
    }
    else
    {
        qDebug()<<"未找到要插入的位置";

    }
}
//删除值为val的链表
void remove_dynamic(LinkNode * header,int delValue)
{
    if(nullptr == header)
        return;
    int place = 0;
    bool flag = true;
    LinkNode * pCurrent = header;
    LinkNode * pfind= header;
    //while循环中,找要删除的数val
    while (pfind->next!=nullptr)
    {
        if(delValue == pfind->next->data)
        {
            flag = false;
            break;
        }
        pfind = pfind->next;
        place++;//最后值就是要删除元素前一个元素的位置
    }
    if(flag == false)//确保有找到这要删除的变量
    {
        LinkNode * del =nullptr;
        for(int i = 0;i<2;++i)
        {
            pCurrent = pCurrent->next;
        }
        del = pCurrent->next;
        pCurrent->next = del->next;
        del->next = nullptr;
    }
    else
    {
        qDebug()<<"未找到该元素";

    }
}
//遍历
void Foreach_dynamic(LinkNode * header)
{
    if(nullptr == header)
        return;
    while (header->next!=nullptr)
    {
        qDebug()<<"输出:"<<header->next->data;
        header = header->next;
    }

}

//清空
void clear_dynamic(LinkNode * header)//接触链表的所有next指针指向即可,从头向尾解除
{
    if(nullptr == header)
        return;
    LinkNode * pCurrent = header;
    LinkNode * delitem = nullptr;

    int size = size_dynamic(header);
    if(size == 0)
    {
        qDebug()<<"大小为0,不用清空";
        return;
    }
    else
    {
        while(pCurrent->next!=nullptr)
        {
            delitem = pCurrent->next;
            pCurrent->next = nullptr;
            pCurrent = delitem;
        }
    }
}
//大小
int size_dynamic(LinkNode * header)
{
    if(nullptr == header)
        return 0;

    int size = 0;
    LinkNode * pCurrent = header;
    while(pCurrent->next!=nullptr)
    {
        ++size;
        pCurrent = pCurrent->next;
    }
    return size;
}
//销毁
void destroy_dynamic(LinkNode * header)
{
    if(nullptr == header)
        return;
    delete header;
}

 

具体执行内容: 

    //动态链表
    qDebug()<<"动态链表";
    LinkNode td1 = {10,nullptr};
    LinkNode td2 = {20,nullptr};
    LinkNode td3 = {30,nullptr};
    LinkNode td4 = {40,nullptr};
    LinkNode td5 = {50,nullptr};
    LinkNode td6 = {60,nullptr};


    LinkNode * dynamic = init_dynamic();
    dynamic->next = &td1;
    td1.next = &td2;
    td2.next = &td3;
    td3.next = &td4;
    td4.next = &td5;
    td5.next = &td6;

    qDebug()<<"遍历";
    Foreach_dynamic(dynamic);
    qDebug()<<"链表大小:"<<size_dynamic(dynamic);

    qDebug()<<"删除30";
    remove_dynamic(dynamic,30);
    qDebug()<<"遍历";
    Foreach_dynamic(dynamic);
    qDebug()<<"链表大小:"<<size_dynamic(dynamic);

    qDebug()<<"删除90(链表中没有的元素)";
    remove_dynamic(dynamic,30);

    //插入元素
    qDebug()<<"插入元素400,在50的前面";
    LinkNode td7 = {400,nullptr};

    InsertByValue_dynamic(dynamic,50,&td7);
    qDebug()<<"遍历";
    Foreach_dynamic(dynamic);
    qDebug()<<"链表大小:"<<size_dynamic(dynamic);

    qDebug()<<"清空";
    clear_dynamic(dynamic);
    qDebug()<<"链表大小:"<<size_dynamic(dynamic);

    qDebug()<<"验证:td1"<<td1.next<<endl
           <<"验证:td2"<<td2.next<<endl
          <<"验证:td3"<<td3.next<<endl
         <<"验证:td4"<<td4.next<<endl
        <<"验证:td5"<<td5.next<<endl
       <<"验证:td6"<<td6.next<<endl;

    qDebug()<<"销毁";
    destroy_dynamic(dynamic);

输出:

 

 

 

 

 

 

 

 

 

大小插入都是灵活的

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值