C++基础---链表

1. 链表

1.1 C++中的结构体和类的区别

  • 在C++中,结构体与类基本相同,唯一不同的是:
    (1)结构体:成员默认为公有成员
    (2)类:成员默认为私有成员

1.2 链表的定义

  • 链表:是一种物理存储单元上非连续、非顺序的存储结构
  • 链表:一系列结点(链表中每一个元素称为一个结点)组成
  • 链表:它解决了数组(就像容器)不可调节大小的缺陷,它可以将一个容器分解成若干个小容器,每一个小容器放入合适大小的元素,然后根据需要将它们链接起来

1.3 链表元素的定义

  • 链表中数据元素的逻辑顺序:是通过链表中的指针链接次序实现的。
  • 链表中每个元素(结点)包括两个部分:
    (1)存储数据元素的数据域
    (2)存储下一个结点地址的指针域
  • 声明一个链表结构,如:

    struct book
    {
        int num; float price; //数据域
        book *next; //指针域
    }
    <=>等价于
    class book
    {
    public: 
        int num; float price; //数据域
        book *next; //指针域
    }

1.4 静态链表

  • 静态链表:链表中所有结点的数据内存中的分布都是在编译时就确定好了的,程序运行后不能进行改动
  • 代码示例:静态链表的实现

    
    #include <iostream>
    
    using namespace std;
    struct book
    {
        int num; float price; //数据域
        book* next; //指针域
    }
    void main()
    {
        book x, y, z, *head, *p;
        x.num = 10000; x.price = 14.7; 
        y.num = 10005; y.price = 12.7; 
        z.num = 10008; z.price = 44.7; 
        head = &x;//将x变量结构的开始地址作为一个结点赋给头指针head
        x.next = &y;//将y变量结构的开始地址作为一个结点赋给x变量结构的next指针成员
        y.next = &z;//将z变量结构的开始地址作为一个结点赋给y变量结构的next指针成员
        z.next = NULL;//将z变量结构的next指针成员赋为空,即表示该结点是个尾结点
        p = head;//将p指针指向头结点head
        while(p)
        {
            cout<<p->num<<"\t"<<p->price<<endl;
            p = p->next;
        }
        system("pause");
    }

1.5 动态链表

  • 动态链表:链表结构也可以是动态地分配存储的,即在需要时才开辟结点的存储空间
    注:动态链表的操作中将只使用new和delete。如:
    book* p = new book;
    delete p;
  • 示例代码:动态链表的创建

    
    #include <iostream>
    
    
    #include <string> 
    
    using namespace std;
    struct book
    {
        int num; float price; //数据域
        book* next; //指针域
    }
    book* head = NULL; //声明了一个指向book结构的全局指针变量head
    book* creat()
    {
        book *p1, *p2;
        p1 = new book; //在堆中新建了一个book类对象或叫结点,并将指针p1指向它
        head = p1;
        p2 = p1;
        cout<<"请输入图书的编号,以0结束"<<endl;
        cin>>p1->num;
        if (p1->num!=0)
        {
            cout<<"请输入图书的价格"<<endl;
            cin>>p1->price;
        } 
        else
        {
            delete p1;
            p2 = NULL;
            head = NULL;
            return head;
        }
        while(p1->num != 0)
        {
            p2 = p1; //用p2来保存p1的地址,也就是上次创建成功结点的位置
            p1 = new book; //作为下一个节点的指针p1
            cout<<"请输入图书的编号,以0结束" <<endl;
            cin>>p1->price;
            if (p1->num!=0)
            {
                cout<<"请输入图书的价格"<<endl;
                cin>>p1->price;
            } 
            p2->next = p1; //将p1的值付给p2->next,由于目前p1所指向的是个新结点,而p2指向的是第1个结点,因此p2->next = p1也就是将新结点的地址赋给第1个结点的next指针成员
        }
        delete p1; //会删除掉最后一次创建的结点
        p2->next = NULL; //将最后一次创建的结点的上一个结点的next成员赋为空,这样该结点就变成了尾结点,它不再指向任何结点
        return head;
    }
    void main()
    {
        creat();
    }
  • 示例代码:遍历显示动态链表

    void Showbook(book* head)
    {
        while(head)
        {
            cout<<head->num<<"\t"<<head->price<<endl;
        }
    }
  • 示例代码:删除动态链表中的指定结点

    void DeleteNode(book* head, int num)
    {
        book* l;
        if (head->num == num) 
        {
            l = head; //将头结点的地址赋给指针l
            head = head->next; //用头指针head来访问第1个结点的next成员,并将next成员所存放的第2个结点的地址赋给head,这样head就指向了第2个结点
            ::head = head; //跟着在将head的值赋给全局的head
            cout<<"操作成功"<<endl;
            return;
        }
        while (head)
        {
            if (head->next == NULL)
            {
                cout<<"找不到要删除的编号。"<<endl;
                return;
            }
            if (head->next->num == num) 
            {
                l = head->next;
                head->next = l->next;
                delete l;
                cout<<"操作成功"<<endl;
                return;
            }
            head = head->next; //进入下一次循环
        }
        cout<<"找不到要删除的编号。"<<endl;
    }
  • 示例代码:在动态链表尾端插入结点

    void InsertNode(book* head, int num, float price)
    {
        book* l;
        book* list = new book;
        while (head)
        {
            l = head;
            head = head->next;
        }
        list->num = num;
        list->price = price;
        list->next = NULL;
        l->next = list; //在尾端插入结点list
    }
  • 示例代码:统计动态链表总结点数

    int CountNode(book* head)
    {
        int count = 0;
        while (head)
        {
            count++;
            head = head->next;
        }
        return count;
    }

参考文献:
[1]《C++全方位学习》范磊——第十五章
[2] 百度搜索关键字:C++链表、结构体与类的区别、链表元素、静态链表、动态链表

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值