day 4线性表之链表(上)

单链表的定义

由于顺序表的插入删除操作需要移动大量的元素,影响了运行效率,因此引入了线性表的链式存储——单链表。

单链表通过一组任意的存储单元来存储线性表中的数据元素,不需要使用连续的存储单元,因此它不要求逻辑上相邻的两个元素物理位置上也相邻

单链表的特点:

  1. 单链表不要求逻辑上相邻的两个元素在物理位置上也相邻,因此不需要连续的存储空间。

  1. 单链表是非随机的存储结构,既不能直接找到表中某个特定的结点。查找某个特定的结点时,需要从表头开始遍历,依次查找。对于每个链表结点,除了存元素自身的信息外,还需要存放一个指向后继的指针。

单链表的创建

1.单链表中节点类型的描述:


typedef struct node{       //定义单链表结点类型
    data_t data;           //数据域,可以是别的各种数据类型,本文同意用int类型
    struct node *next;     //指针域
}listnote, *linklist;

2.初始化

通常会用头指针来表示一个单链表头指针为NULL时表示一个空表。但是,为了操作方便,会在单链表的第一个结点之前附加一个结点,称为头结点。头结点的数据域可以不设任何信息,也可以记录表长等信息。头结点的指针域指向线性表的第一元素结点。如下图所示:

头结点和头指针的区分:不管带不带头结点,头指针始终指向单链表的第一个结点,而头结点是带头结点的单链表中的第一个结点,结点内通常不存储信息。

 那么单链表的初始化操作就是申请一个头结点将指针域置空


linklist list_create() {
    linklist H;

    H = (linklist)malloc(sizeof(listnode));   //申请结点空间
    if (H == NULL) {                          //判断空间是否申请成功
        printf("malloc failed\n");
        return H;
    }

    H->data = 0;                                //将头结点内容置空
    H->next = NULL;                             //将next设置为NULL,初始长度为0的单链表
}

建立单链表


//头插法建立单链表
LinkList HeadInsert(LinkList &L){
    InitList(L); //初始化
    int x;
    scanf();
    while(x!=9999){ //输入9999表示结束
        LNode *s = (LNode *)malloc(sizeof(LNode));
        s->data = x;
        s->next = L->next;
        L->next = s;
        cin>>x;
    }
    return L;
}

1、尾插法建立单链表

 所谓尾插法建立单链表,就是将新结点插入到当前链表的表尾。如下图所示:

算法思想:

(1).首先初始化一个单链表,然后声明一个尾指针q,让q始终指向当前链表的尾结点;

(2).循环向单链表的尾部插入新的结点*p,将尾指针q的next域指向新结点;

(3).再修改尾指针q指向新结点,也就是当前链表的尾结点;

(4). 最后别忘记将尾结点的指针域置空。

(5). 实现代码:


int list_tail_insert(linklist H, data_t value) {
    linklist p;
    linklist q;
    if (H == NULL) {
        printf("malloc failed\n");    //若单链表空间申请失败则直接退出
        return -1;
}
//1 new node p
if((p = (linklist)malloc(sizeof(listnode))) == NULL) { //判断new node p是否成功,失败则直接退出
    printf("malloc failed\n");
    return -1;
}
p->data = value;
p->next = NULL;
//2 locate tail node 
q = H;
while(q->next != NULL) {
    q = q->next;
}
// 3 insert 尾部插入
    q->next = p;
    return 0;
}

2、按位查找操作

按位查找函数结构


 Getlinklist(h, i-1) 

算法思想

  1. 判断链表是否存在;

2.寻找索访问结点的位置;

3.判断该位置是否越界,若未越界,则返回该结点位的地址。

代码实现


linklist list_get(linklist H, int pos) {
    linklist p;
    int i;
//1、判断链表是否存在
    if (H == NULL) {   
        printf("H is NULL\n");
        return NULL;
}
    if (pos == -1) {
        return H;
}
//2 寻找访问结点的位置
     p = H;
     i = -1;
while(i < pos) {
     p = p->next;
// 3 判断位置是否越界
     if (p == NULL) {
         printf("pos is invalid\n");
         return NULL;
      }
        i++;
    }
  return p;
}   

3、按位插入操作

 按位插入函数结构


insertLinklist(H, x, i) 

功能:实现将x插在ai之前;

算法思路:

(1)调用函数Getlinklist(h, i-1)函数找到ai的前驱指针变量p;

(2)申请一个指针变了q存入x,并将其插入p指向的结点的后面;

(3)更新链表。

代码实现


int list_intser(linklist H, data_t value, int pos) {
    linklist p, q;
    if (H == NULL) {
        printf("H is NULL\n");
        return -1;
       }
//1 locate node p (pos-1)
    p = list_get(H, pos-1);
    if (p == NULL) {
        retirn -1;
    }
//2 new node q
    if ((q = (linklist)malloc(sizeof(listnode))) == NULL) {
        printf("malloc failed\n");
        return -1;
    }
    q->data = value;
    p->next = q;
//3 insert
    q->next = p->next;   //防止ai丢失先进性此步
    p->bext = q;
    return 0;
}

4、遍历单链表

 算法思想:声明一个指针变量p,从头结点指向的第一个结点开始,如果p不为空,那么就输出当前结点的值,并将p指向下一个结点,直到遍历到最后一个结点为止。

 实现代码:


//遍历操作
int list_show(linklist H) {
    linklist p;
    if (H == NULL) {
        printf("H is NULL\n");
        return -1;
    }
    p = H;
while(p->next != NULL) {
    printf("%d ", p->next->data);
    p = p->next;
    }
    puts("");

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值