【SUFE】数据结构笔记——1. 线性表

线性表

GitHub地址
求star(`・ω・´)
原文地址

总述

代码是抽象的——所以我们学习数据结构时尽量自己把图给画出来,自己去模拟这个过程,才能加深印象。

线性链表的创建

这里我们采用while循环创建链表,当输入某一个特定的值(-9999)时停止创建。

基本思路
  1. 首先创建三个node指针,一个指向头head,一个指向尾p,一个作为开辟新结点的工具q。 (代码第4行)
  2. 记得将head初始化为空,然后让p = head(注意,此时的headp都没有“实体”结点,都指向NULL)。 (代码第4, 5行)
  3. head为空:正常地new然后赋值,接着让p指向head; (代码第9~14行)
  4. head不为空:new一个新结点q,对两个成员变量进行赋值。让p->link指向q,接着让p指向新的“尾巴”p = q。 (代码第16~22行)
  5. 返回head即可。 (代码第26行)
出现过的问题
  1. 创建的表的首结点会重复两次。原因就在于☆处,没有再次输入n,导致n的值被用于创建首结点和第二个结点。
需要注意的点
  • 特殊情况:空表和只有一个结点。
代码
NODE* create_link()
{
   
    int n;
    NODE* head = NULL, * p, * q;
    p = head;
    cin >> n;
    while (n != -9999)
    {
   
        if (head == NULL) {
   
            head = new NODE;
            head->data = n;
            head->link = NULL;
            p = head;   //p只需要指向head即可
☆          cin >> n;   //还是需要一个cin,不然n的值没法更新,第一个就会创建两次
        }
        else{
   
            q = new NODE;   //用q创建,然后p再指
            q->data = n;
            q->link = NULL;
            p->link = q;
            p = q;
            cin >> n;
        }
        p->link = NULL;
    }  
    return(head);
}

线性链表的插入

基本思路
  1. 首先确定位置的三种情况:0,中间,>链表长度。其中,后两种可以合成一种情况讨论。
  2. 对于插在头结点的情况,我们直接添加(详情查看代码)。
  3. 对于另外的情况,首先要让指针指到要插入的位置。然后进行插入。
需要注意的点
  • 分类讨论,插在表头的特殊情况
  • 传递的参数需要是引用。 有没有直接传递指针就可以改变的方法呢?
  • (接上一行)有!返回类型设置为NODE*,然后head = insert_link(head)就行了
代码
// NODE* insert_link(NODE *head)
void insert_link(NODE *head) {
       
    int loc;    //作用:记录要插入的位置
    cout << "Where do you want to insert?\n";
    cin >> loc; 
    loc -= 1;   //在原来结点的前面插入
    NODE* pos = head;   //作用是指向要插入的位置

    //insert
    int num;    //该结点的值
    cout << "please input the number\n";
    cin >> num;

    NODE* q = new NODE; //开始创建新的结点
    q->data = num;

    if (loc == -1) {
       //problem: 返回后一切不变,传递的不是指针吗?
        q->link = head;
        head = q;   //为什么它不会改变?传递的是指针,必须要引用指针?
    }
    else {
   
        //find the position
        while (pos->link != NULL && loc) {
     //为什么它不会触发等于NULL的条件?因为↓
            pos = pos->link;    //不可以直接用pos++
            loc--;
        }

        q->link = pos->link;
        pos->link = q;
    }
    //return head;    如果传回指针,就加这句。
}

线性链表的删除

删除链表中值为a的 第一个/所有 结点。

基本思路
  1. 确定特殊情况:为空链表、删除的是头结点
  2. 对于一般情况,即删除的结点在中间。让2个指针指向被删除结点及其前面的结点,然后将前面的结点的link接到下下个结点上,再delete要删除的结点即可。
  3. 对于为空,直接返回传入的参数head即可。
  4. 对于头结点,先用q保存本结点的地址,然后直接让head指向下一个结点,再删除原头结点即可。
需要注意的点
  • 讨论好特殊情况即可
代码
void delete_link(NODE* head, int a) {
      //此处只需要传入头结点即可
    if (head == NULL) {
    //链表为空时
        cout << "链表为空!\n";
        return ;
    }
    NODE* q = head;
    if (q->data == a)
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值