美文网首页
数组模拟单向链表

数组模拟单向链表

作者: 进击的猫 | 来源:发表于2016-12-23 21:15 被阅读0次

链表的定义

链表是一种物理存储单元上非连续、非顺序的存储结构,数据元素的逻辑顺序是通过链表中的指针链接次序实现的。链表由一系列结点(链表中每一个元素称为结点)组成,结点可以在运行时动态生成。每个结点包括两个部分:一个是存储数据元素的数据域,另一个是存储下一个结点地址的指针域。 相比于线性表顺序结构,操作复杂。

单向链表.jpg

模拟链表

结构体模拟链表

先用一个结构体来表示链表的结点类型

struct node{
    int data;
    struct node *next;
};

那么循环输入几个数存入链表中就可以这样写

    head = NULL; // 头指针的初始为空
    for (i = 0; i <= n; i++) {
        
        scanf("%d",&a);
        // 动态申请一个空间,用来存放一个结点,并用临时指针p指向这个结点
        p = (struct node*)malloc(sizeof(struct node));
        // 将数据存储到当前结点的data域中
        p->data = a;
        // 设置当前结点的后继指针指向空,也就是当前结点的下一个结点为空
        p->next = NULL;
        if (head == NULL) {
            // 如果这是第一个创建的结点,则将头指针指向这个结点
            head = p;
        }else{
            // 不是第一个创建的结点,则将上一个结点的后继指针指向当前结点
            q ->next = p;
        }
        p = q;  // 指针q也指向当前结点
    }

那么在这个链表中间插入一个数的话又该如何操作呢?首先用一个临时指针t从链表的头部开始遍历,等到指针t的下一个结点的值比插入的数大的时候,就将插入的数插入到中间即可。

    t= head;    // 从链表头部开始遍历
    while (t != NULL) {// 没有到达链表尾部的时候循环
        // 如果当前结点是最后一个结点或者下一个结点的值大于待插入数的时候插入
        if (t ->next == NULL || t ->next ->data >a) {
            // 动态申请一个空间,用来存放新增的结点
            p = (struct node*)malloc(sizeof(struct node));
            
            p->data = a;
            // 新增结点的后继指针指向当前结点的后继指针所指向的结点
            p->next = t->next;
            // 当前结点的后继指针指向新增结点
            t->next = p;
            break;
            
        }
        t = t->next;
    }
数组模拟单向链表

链表中的每一个结点只有两个部分。我们可以用一个数组data来存储序列中的每一个数。那么每一个数的右边我们就需要再用一个数组right来存放序列中每一个数。

数组模拟单向链表.png

现在需要在8前面插入一个6,只需要将6直接存放在数组data的末尾data[10] = 6。接下来只需要将right[3]改为10,表示新序列中3号元素右边的元素存放在data[10]中。再将right[10]改为4,表示新序列中10号元素右边的元素存放在data[4]中。

插入一个数.png

现在我们可以通过right数组就可以从头到尾遍历整个序列了。下面是完整代码:

int main(int argc, const char * argv[]) {
    
    arrayMethod();

    getchar();
    getchar();
    
    return 0;
}

void arrayMethod(){
    
    int data[101],right[101];
    int i, n, t, len;
    scanf("%d",&n);
    for (i = 1; i<= n; i++) {
        scanf("%d",&data[i]);
    }
    len = n;
    //初始化数组right
    for (i = 1; i <= n; i++) {
        
        if (i != n) {
            right[i] = i+1;
        }else{
            right[i] = 0;
        }
    }
    
    // 直接在data数组末尾添加一个数
    len++;
    scanf("%d",&data[len]);
    
    // 从链表的头部开始遍历
    t = 1;
    while (t != 0) {
        //如果当前结点下一个结点的值大于带插入数,将数插入到中间
        if (data[right[t]] > data[len]) {
            // 新插入数的下一个结点标号等于当前结点的下一个编号
            right[len] = right[t];
            // 当前结点的下一个结点编号就是新插入的编号
            right[t] = len;
            break;
        }
        t = right[t];
    }
    
    // 输出链表
    t =1;
    while (t != 0) {
        printf("%d",data[t]);
        t = right[t];
    }
}

输入:


Snip20161223_6.png

结果为:


Snip20161223_7.png

相关文章

  • 数组模拟单向链表

    链表的定义 链表是一种物理存储单元上非连续、非顺序的存储结构,数据元素的逻辑顺序是通过链表中的指针链接次序实现的。...

  • HashMap

    HashMap 原理 HashMap由数组和单向链表构成。 HashMap由单向链表和数组构成, 默认初始化数组大...

  • 静态链表及C#实现

    静态链表 静态链表是用数组模拟动态链表。 静态链表结构描述 首先,静态链表使用数组来模拟动态链表。数组存放一个节点...

  • 算法与数据结构:链表

    链表 链表还分为单向链表和双向链表, 但是这篇文章只说单向链表 , 下次再讲双向链表 . 链表和数组的区别 ? 链...

  • HashMap 源码分析

    一、HashMap内部的数据结构是什么? 数组+单向链表 二、怎么验证内部结构是数组和单向链表? a、数组:通过H...

  • HashMap,LinkedHashMap简析及LruCache

    简介 HashMap:数组+单向链表 LinkedHashMap: HashMap + 双向循环链表 LruCac...

  • Ucos系统常用的数据结构有哪些?

    1)表 链表 表中主要了解链表,尤其是单向链表。 2)数组 一维数组 二维数组 使用数组有什么好处,在c语言中,数...

  • 【数据结构与算法 - Swift实现】02 - 链表

    与数组一样,链表也是存储元素的集合。 链表的分类 单向链表 单向链表的节点存储了下一个节点的地址。如下图: 双向链...

  • HashMap数据结构分析

    基本结构: 数组+单向链表 元素: Node,包含key value Node(next) 基本限制 数组默认...

  • 单向链表模拟实现

    模拟LinckedList实现增删改查 ps:未考虑并发情况 链表结构优点,删除,插入数据速度快,占用内存小。

网友评论

      本文标题:数组模拟单向链表

      本文链接:https://www.haomeiwen.com/subject/bltlvttx.html