线性表
Posted sanweizuiji
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了线性表相关的知识,希望对你有一定的参考价值。
1 线性表
1.1 定义
1.2 逻辑结构
1.3 基本操作
创销、增删改查
2 用顺序存储的方式来实现线性表(顺序表)
2.1 定义
2.2 特点
随机访问,能在O(1)时间内找到第i个元素
存储密度高
拓展容量不方便
插入、删除数据元素不方便
2.3 基本操作的实现
#include<cstdio>
#include<cstring>
#define MaxSize 10
using namespace std;
// 顺序表数据结构
typedef struct
// 顺序表元素
int data[MaxSize];
// 顺序表当前长度
int length;
SqList;
// 初始化顺序表函数,构造一个空的顺序表
void InitList(SqList &L)
// memset: 将某一块内存中的内容全部设置为指定的值
memset(L.data, 0, sizeof(L));
L.length = 0;
// 在表 L 中的位置 i 上插入指定元素 e
void ListInsert(SqList &L, int i, int e)
if (i < 1 || i > L.length + 1)
printf("位置 i 无效\\n");
else if (L.length >= MaxSize)
printf("当前存储空间已满\\n");
else
// 位置 i 及之后元素后移
for (int j = L.length; j >= i; j--)
L.data[j] = L.data[j - 1];
L.data[i - 1] = e;
L.length++;
// 删除函数 删除位置 i 的元素 i 之后的元素依次前移
void ListDelete(SqList &L, int i)
if (i < 1 || i > L.length)
printf("位置 i 无效\\n");
else
// 位置i之后元素依次前移覆盖
for (int j = i; j <= L.length - 1; j++)
L.data[j - 1] = L.data[j];
L.length--;
// 按位置从小到大查找第一个值等于 e 的元素 并返回位置
int LocateElem(SqList L, int e)
for (int i = 0; i < L.length; i++)
if (L.data[i] == e)
return i + 1;
return -1;
// 输出顺序表中的所有元素
void PrintList(SqList L)
printf("打印顺序表 -----\\n");
if (L.length == 0)
printf("该顺序表为空\\n");
for (int i = 0; i < L.length; i++)
printf("data[%d] = %d\\n", i, L.data[i]);
printf("--------------\\n");
int main()
SqList L;
printf("初始化一个顺序表\\n");
InitList(L);
PrintList(L);
printf("向位置 1 插入一个元素 123123\\n");
ListInsert(L, 1, 123123);
PrintList(L);
printf("向位置 1 插入一个元素 345345\\n");
ListInsert(L, 1, 345345);
PrintList(L);
printf("获取元素 123123 的位置\\n");
printf("%d\\n", LocateElem(L, 123123));
printf("删除位置 1 上的元素\\n");
ListDelete(L, 1);
PrintList(L);
printf("获取元素 123123 的位置\\n");
printf("%d\\n", LocateElem(L, 123123));
return 0;
例 线性表的顺序存储结构是一种(随机存取的存储结构)
3 用链式存储的方式来实现线性表(链式表)
3.1 单向链表
#include <cstdio>
#include <cstdlib>
struct linkedListNode
int data;
struct linkedListNode *next;
;
// 将 struct linkedListNode 简化为 linkedListNode
typedef struct linkedListNode linkedListNode;
// 初始化链表
// 如果不带头节点的话,进行第一个节点的插入或删除操作时需要特殊处理(要单独修改头指针的指向),比较繁琐
void initLink(linkedListNode *&L)
// 创建一个头结点
L = (linkedListNode *) malloc(sizeof(linkedListNode));
L->next = NULL;
// 获取指向第 index 个结点的指针
linkedListNode *getLinkedListNode(linkedListNode *l, int index)
if (index < 0)
return NULL;
else
linkedListNode *temp = l;
// nodeNum 表示节点个数,从第 0 个节点开始(第 0 个节点就是头节点)
for (int nodeNum = 0; temp != NULL && nodeNum < index; nodeNum++)
temp = temp->next;
return temp;
// 在第 index 个结点的位置上插入一个结点
void listInsert(linkedListNode *&l, int index, int data)
if (index < 1)
printf("插入位置的区间应为 [1,n]\\n");
else
// 获取指向第 index-1 个结点的指针
linkedListNode *temp = getLinkedListNode(l, index - 1);
if (temp == NULL)
printf("第 %d 个节点不存在,所以无法后插\\n", index - 1);
else
// 创建插入结点 c
linkedListNode *c = (linkedListNode *) malloc(sizeof(linkedListNode));
c->data = data;
// 向链表中插入结点
c->next = temp->next;
temp->next = c;
// 删除结点
void listDelete(linkedListNode *l, int index)
if (index < 1)
printf("删除元素的位置的区间应为 [1,n]\\n");
else
// 获取指向第 index-1 个结点的指针
linkedListNode *temp = getLinkedListNode(l, index - 1);
if (temp == NULL)
printf("第 %d 个节点不存在\\n", index - 1);
else if (temp->next == NULL)
printf("第 %d 个节点不存在\\n", index);
else
linkedListNode *delNode = temp->next;
temp->next = delNode->next;
// 手动释放该结点,防止内存泄漏
free(delNode);
void printList(linkedListNode *L)
printf("\\n");
printf("打印链表 -----\\n");
// 定义 temp 指针指向头结点
linkedListNode *temp = L;
// 只要 temp 指针指向的结点的 next 不为空,就执行输出语句,否则结束函数并输出提示语
if (temp->next)
while (temp->next)
temp = temp->next;
printf("%d ", temp->data);
printf("\\n");
else
printf("该链表为空\\n");
printf("------------\\n");
printf("\\n");
int main()
printf("初始化链表\\n");
linkedListNode *pLinkedListNode;
initLink(pLinkedListNode);
printList(pLinkedListNode);
printf("在位置 1 插入一个元素 123123,在位置 2 插入一个元素 345345\\n");
listInsert(pLinkedListNode, 1, 123123);
listInsert(pLinkedListNode, 2, 345345);
printList(pLinkedListNode);
printf("删除位置 1 的元素\\n");
listDelete(pLinkedListNode, 1);
printList(pLinkedListNode);
return 0;
3.2 双向链表
#include <cstdio>
#include <cstdlib>
struct DNode
int data;
struct DNode *prior;
struct DNode *next;
;
typedef struct DNode DNode;
void initDLinkList(DNode *&l)
l = (DNode *) malloc(sizeof(DNode));
if (l == NULL)
printf("申请内存不足失败");
else
l->prior = NULL;
l->next = NULL;
// 获取指向第 index 个结点的指针
DNode *getDNode(DNode *l, int index)
if (index < 0)
printf("获取结点的位置区间应为 [0,n]\\n");
return NULL;
else
DNode *temp = l;
// nodeNum 表示节点个数,从第 0 个节点开始(第 0 个节点就是头节点)
for (int nodeNum = 0; temp != NULL && nodeNum < index; nodeNum++)
temp = temp->next;
return temp;
DNode *createDNode(int data)
DNode *newNode = (DNode *) malloc(sizeof(DNode));
if (!newNode)
printf("分配空间失败,请检查内存\\n");
return NULL;
//[2]初始化新节点
newNode->data = data;
newNode->next = NULL;
newNode->prior = NULL;
//[3]返回节点地址
return newNode;
// 在第 index 个结点的位置上插入一个结点
void dListInsert(DNode *l, int index, int data)
if (index < 1)
printf("位置的区间应为 [1,n]\\n");
else
DNode *s = createDNode(data);
if (s == NULL)
printf("根据输入数据新建的结点为空");
else
// 获取指向第 index-1 个结点的指针
DNode *temp = getDNode(l, index - 1);
if (temp == NULL)
printf("第 %d 个节点不存在,所以无法后插\\n", index - 1);
else
s->next = temp->next;
if (temp->next != NULL)
temp->next->prior = s;
s->prior = temp;
temp->next = s;
// 删除结点
void dLisDelete(DNode *l, int index)
if (index < 1)
printf("删除元素的位置的区间应为 [1,n]\\\\n");
else
// 找到待删除元素的前一位 *temp
DNode *temp = getDNode(l, index - 1);
if (temp == NULL)
printf("第 %d 个节点不存在,所以无法删除它后边的结点\\n", index - 1);
else
DNode *nodeToBeDeleted = temp->next;
if (nodeToBeDeleted == NULL)
printf("第 %d 个节点不存在\\n", index);
else
temp->next = nodeToBeDeleted->next;
// 若 *nodeToBeDeleted 不是最后一位元素
if (nodeToBeDeleted->next != NULL)
nodeToBeDeleted->next->prior = temp;
free(nodeToBeDeleted);
void printList(DNode *L)
printf("\\n");
printf("打印链表 -----\\n");
// 定义 temp 指针指向头结点
DNode *temp = L;
// 只要 temp 指针指向的结点的 next 不为空,就执行输出语句,否则结束函数并输出提示语
if (temp->next)
while (temp->next)
temp = temp->next;
printf("%d ", temp->data);
printf("\\n");
else
printf("该链表为空\\n");
printf("------------\\n");
printf("\\n");
int main()
DNode *L;
initDLinkList(L);
dListInsert(L, 1, 123123);
dListInsert(L, 1, 345345);
dListInsert(L, 3, 575685);
printList(L);
dLisDelete(L, 3);
dLisDelete(L, 1);
printList(L);
return 0;
3.3 单向循环链表
3.4 双向循环链表
3.5 静态链表
分配一整片连续的内存空间,各个结点集中安置
以上是关于线性表的主要内容,如果未能解决你的问题,请参考以下文章