数据结构链表的初始化插入删除_数据结构小结

各种数据结构的定义

1 线性表

1.1 顺序存储

线性表的顺序存储结构,指的是用一段地址连续的存储单元依次存储线性表的数据元素。

C语言定义:

# define MAXSIZE 20
typedef int ElemType;
typedef struct
{
  ElmeType data[MAXSIZE];
  int length;      // 线性表当前的长度;
}sqlist;

注:我们上面封装的这个顺序存储结构的线性表,事实上就是对数组的封装,只是又加了一个变量(属性)"length"来表示当前顺序存储线性表的当前数据长度。

1.2 链式存储

我们把存储数据元素信息的域称为数据域,把存储直接前继或后继位置的域称为指针域。指针域中存储的信息称为指针或链。这两部分信息组成数据元素成为存储映像,称为结点(Node)。n个节点链接成一个链表,即为线性表的链式存储结构

1.2.1单链表

typedef struct Node
{
  ElemType data; // 数据域
  struct Node *next;  // 指针域,指向下一个节点,所以指针结构类型是下一个节点的类型:Node
} Node;  // 其实下面的*LinkList可以加在这里,下面就不用写了;

typedef struct Node *LinkList;  // 取别名

可以看到,单链表的节点仅由 存放数据元素的数据域data存放指向下一个节点地址的指针 组成。

1.2.2静态链表

在没有高级语言,没有指针之前,大佬们用数组来代替指针来描述单链表(但是本质仍是数组,所以在生成之初就限制了单链表的大小),称为游标实现法。图示如下:

数据结构链表的初始化插入删除_数据结构小结_第1张图片
静态链表游标实现

C语言结构定义:

#define MAXSIZE 1000
type struct
{
  ElemType data;  // 数据域
  int cur;        // 游标
}Component, StaticLinkList[MAXSIZE];

因为静态链表是用数组模拟的,初始化一个静态链表相当于初始化数组,代码如下:

Status InitList(StaticLinkList space)
{
  int i;
  for(i=0; i < MAXSIZE-1; i++)
    space[i].cur = i + 1;
  space[MAXSIZE-1].cur = 0;

  return OK;
}

1.2.3循环链表

1)单向循环链表

单链表中终端节点的指针由空指针(NULL)改为指向头结点,就是整个单链表形成一个环,这种头尾相连的单链表称为单向循环链表,简称循环链表。

注:并非循环链表一定有头结点;

C语言结构定义:

typedef struct CLinkList
{
  ElmeType data;
  struct CLinkList *next;
}node;

注:循环链表和单链表的主要差异为判断空链表的方式,单链表:head->next是否为NULL;循环链表:head->next是否等于head。

2)双向循环链表

typedef struct DualNode
{
  ElemType data;
  struct DualNode *prior; // 前驱节点;
  struct DualNode *next;  // 后驱节点;
}DualNode, *DuLinkList;

2 栈与队列

2.1 栈的顺序存储结构

定义:栈(stack)是一个先进先出(Last in first out, LIFO)的线性表,它要求只能在表尾进行插入和删除操作。

栈本质是一个线性表。特点:后进先出,即只能在表尾进行操作。对栈来说,这个线性表的表尾称为栈的栈顶(top),表头称为栈的栈底(bottom)。栈的插入操作(Push),叫进栈,或入栈、压栈;栈的删除操作(Pop),叫出栈

常用的是栈的顺序存储结构

typedef struct
{
    ElemType *base;   //这里的ElemType是对某数据类型的重命名,如char
    ElemType *top;
    int stackSize;
}sqStack;

2.2 栈的链式存储

// 栈中的每一个元素结构
typedef struct StackNode
{
    ElemType data; //存放栈的数据
    struct StackNode *next;
}StackNode, *LinkStackPtr;

// 栈的指针和元素计算器
typedef struct LinkStack
{
    LinkStackPtr top; //top指针
    int count; //栈元素计数器
}

2.3 队列的链式存储

队列(queue)是只能在一端进行插入操作,在另一端进行删除操作的线性表。

与栈相反,队列是一种先进先出(First In First Out, FIFO)的线性表。

与栈相同的是,队列也是一种重要的线性结构,实现队列同样需要顺序表或者链表作为基础。

与栈相反,队列通常用链表来实现

typedef struct QNode
{
    ElemType data;
    struct QNode *next;
} QNode, *QueuePtr;
typedef struct
{
    QueuePtr front, rear; // 队头指针,队尾指针;
}LinkQueue;

2.4 队列的顺序存储

顺序存储实现的队列,入队操作的时间复杂度为O(1),但是出队时,所有元素都需要往前移位,时间复杂度为O(n)。

解决方法是可以加一个队头指针,指向队列的第一个元素,这样出队操作复杂度也可为O(1)了,但这时的队列会存在假溢出现象,如下图所示:

数据结构链表的初始化插入删除_数据结构小结_第2张图片
队列的假溢出

解决方法是,如果队尾满了就从头开始,形成头尾相接的循环,即循环队列。

2.4.1 循环队列

循环队列的容量是固定的,并且队头队尾指针都可以随着元素入队出队发生改变,这样,在逻辑上就像一个环形的存储空间。

但需注意的是,实际内存中,不会有真正的环形存储区,只是用顺序表模拟出逻辑上的循环。

实现:让front和rear指针不断+1,采用取模运算(即取余数)处理,这样即使超出了地址范围,也会从头开始。

  • (front+1)%QueueSize
  • (rear+1)%QueueSize

C语言定义

#define MAXSIZE 100
typedef struct
{
    ElemType *base; // 用于存放分配的内存空间的基地址;
    int front;
    int rear;
}*CycleQueue;

3 树

参考链接:小甲鱼的数据结构

你可能感兴趣的:(数据结构链表的初始化插入删除)