数据结构代码集训day6(适合考研、自学、期末和专升本)

今日主要写写指针、单链表结构体、单链表的建表方法!


指针结构体可以算的上是c语言里面最重要的两个东西了。

指针变量和普通的变量不同,指针变量里面存的是地址

        假如我们定义了一个int型的指针变量A(指针变量也需要声明类型),一个int型的变量B。这个时候我们将B的地址赋值给A,A=&B,这时候A里面存的就是B变量在内存中的地址了。

        这里的内存是瞎标的,于是我们可以通过*A(这里的*表示解引用)来修改变量B的值,这种通过访问地址来找其他变量的方式就叫指针,我们通常可以通过图示的方法来理解指针,

        int *A=B,也可以叫A指向了B(B必须为int型变量)。


        OK,接着来看单链表的结构体定义:

 typedef struct Lnode{

    int data;

    Lnode *next;

}Lnode,*Linklist;

         一步一步的拆分,首先定义了一个结构体struct Lnode,里面有两个成员变量,一个是data域存单链表的值,另一个是指针域(这个指针域的类型就是Lnode型的),存的是下一个单链表结点的地址。由于结构体里规定了Lnode的类型,所以这个单链表的指针只能指向这个结构体,而不能指向所有的非struct Lnode变量!

        然后再来说说typedef,这个是重命名的意思,将struct Lnode重命名为Lnode,后面定义单链表变量时直接Lnode p就行了,效果等同于struct Lnode p;没错,就是为了偷懒少打点代码而已!后面的*Linklist就代表将Lnode *重命名为Linklist,我们定义结构体指针的时候直接Linklist q,效果等同于Lnode *,也等同于struct Lnode *

        这就是我们定义的单链表结构体啦,原则上来说data和next的位置是可以互换的!

        如果互换,画起来感觉有点怪异,不过效果都是一样的,新手还是按规矩来吧。

        注意,两幅图里面的指针指向的均是结构体,而不是单独的next域或者指针域;通俗点说,如果我们定义了Lnode *p=L(L为一个单链表结点),这里的P指向的是L这个结点全部,而不是该结点的next域或者data域! 


再来说说单链表的插入和删除结点操作!

        单链表的插入操作很好说,就是修改指针域就行了。假如有这样的表,我们要在2和4的中间插入3这个结点

        我们只需要修改2和3的指针域就行了,让2的next域指向3,3的next域指向4即可!

        然后是删除操作,还是上面那个表,我们要把刚插入进去的3删除了,只需修改2的指针域,让2的next域指向4就行了,再free掉3这个结点就行了,其实3这个结点free不free无所谓的,因为你从单链表表头开始遍历,根本找不到3这个结点,但考试还是得删!

        


        ok,开始单链表的创建过程了,单链表的建表有两种方法,头插法尾插法

        头插法就是在插入时,新的结点不断插入到当前链表的表头(也就是头结点的后面)。解释一下头结点,头结点是为了方便运算的实现而提出来的,他是一个特殊的结点,他的data域不存放任何数据,他的指针域指向表头结点。带头结点的单链表如下:

        一般我们会用一个L指针指向头结点,这样L->next恒为表头结点!(指针访问结构体成员用->)。

头插法代码如下:

Linklist list_insertbyhead(Linklist &L){

    Lnode *s;

    int x;

    // 创建头节点

    L = new Lnode;

    L->next = NULL;

    cin >> x;

    while(x!=9999){

        s = new Lnode;

        s->data = x;

        s->next = L->next;

        L->next = s;

        cin >> x;

    }

    return L;

}

        这个函数类型为Linklist,说明返回值必须为指针!因为Linklist=Lnode *,s->next = L->next; L->next = s;就是不断往表头插入新结点的过程!设置循环条件,当手动输入9999时停止建表!

        实践一下:(由于头插法是不断往表头插入结点,所以打印表数据时是倒着的)

        尾插法:这个好理解点,就是不断往表尾追加结点,所以需要一个辅助指针s,一直指向表尾,插入结点后更新这个尾指针(尾指针一直指向表尾结点)!

Linklist list_insertbytail(Linklist &L){

    Lnode *s;

    int x;

    L = (Lnode*)malloc(sizeof(Lnode));

    L->next = NULL;

    Lnode *r = L;

    cin >> x;

    while(x!=9999){

        s = (Lnode*)malloc(sizeof(Lnode));

        s->data=x;

        s->next=NULL;

        r->next = s;

        r=r->next;        // 更新尾指针

        cin >> x;

    }

    return L;

}

        实践一下:

完整代码如下:(在vscode环境下成功跑通)

#include <iostream>
#include <cstdio>
#include <ctime>
using namespace std;

// 单链表结构体定义
typedef struct Lnode{
    int data;
    Lnode *next;
}Lnode,*Linklist;


// 头插法建立单链表
Linklist list_insertbyhead(Linklist &L){
    Lnode *s;
    int x;
    // 创建头节点
    L = new Lnode;
    L->next = NULL;
    cin >> x;
    while(x!=9999){
        s = new Lnode;
        s->data = x;
        s->next = L->next;
        L->next = s;
        cin >> x;
    }
    return L;

}

// 尾插法建立单链表
Linklist list_insertbytail(Linklist &L){
    Lnode *s;
    int x;
    L = (Lnode*)malloc(sizeof(Lnode));
    L->next = NULL;
    Lnode *r = L;
    cin >> x;
    while(x!=9999){
        s = (Lnode*)malloc(sizeof(Lnode));
        s->data=x;
        s->next=NULL;

        r->next = s;
        r=r->next;
        cin >> x;
    }
    return L;
}


int main(){
    Linklist L;
    list_insertbyhead(L);
    // list_insertbytail(L);
    Lnode *p = L->next;
    printf("list:");
    while (p != NULL) {
        printf("%d-> ",p->data);
        p = p->next;
    }
    printf("null");
    printf("\n");
    return 0;
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值