【数据结构】线性表_复习笔记总结
一、顺序存储
- 简单理解就是
用结构体存着的数组1. 结构体定义
typedef int Position;
typedef struct LNode * PtrToLNode;
struct LNode
{
ElmenetType Data[ MAXSIZE ]; // 存储数据信息
Position Last; // 存储线性表最后一个元素的位置
};
typedef PtrToLNode List;2. 初始化空表
List MakeEmpty()
{
List PtrL; // 定义线性表的头结点
PtrL = (List )malloc(sizeof(struct LNode)); // 为整个线性表分配空间
PtrL->Last = -1; // 此时线性表为空,最后一个元素指向-1
return PtrL; // 返回头结点
}3. 查找元素
在线性表 PtrL 中查找给定元素 X
思路: 遍历整个线性表,找到就返回 X 所在位置 i ,找不到就返回 -1int Find(ElementType X, List PtrL)
{
int i = 0;
// 从第一个元素遍历到最后一个元素,若数值等于X就跳出
while (i <= PtrL->Last && PtrL->Data[i] != X ) i ++;
if (i > PtrL->Last ) return -1; // 线性表中没有X,返回-1
else return i;
}
4. 插入元素
将给定元素 X 插入到线性表 PtrL 的第 i 个位置
思路: 线性表==从后往前==,把第 i 个位置到最后一个位置(也就是 Last - 1 的位置)的数全往后挪一个,目的是把第 i 个位置腾出来放新插入的元素,最后记得让Last ++
- 关于为什么从后往前呢? 因为从后往前挪才能保证每个元素都没有丢失,从前往后挪,前一个元素会把后一个元素的值覆盖掉
void Insert(ElementType X, int i, List PtrL )
{
int j;
if (PtrL->Last == MAXSIZE - 1) // 此时表示线性表存满,不能插入元素
{
cout << "FULL.";
return;
}
if (i < 1 || i > PtrL->Last + 2) // 此时给定的位置 i 不合法
{
cout << "The location is not legal.";
return;
}
for (j = PtrL->Last; j >= i - 1; j -- ) // 第i个元素其实是在数列中的第i-1啦
PtrL->Data[j + 1] = PtrL->Data[j];
PtrL->Data[i - 1] = X; // 挪完之后赋值
PtrL->Last ++; // 不要忘了把线性表最后一个元素的位置也往后挪一个
return;
}5. 删除元素
删除线性表 PtrL 中第 i 个元素
思路: 线性表==从前往后==,把从第 i + 1 个元素开始到最后一个元素全部往前挪一位,覆盖掉第 i 个位置的元素,相当于删掉了第 i 个元素
- 为什么不从后往前挪的原因和上面那条一样
void Delete(int i, List PtrL)
{
int j;
if (i < 1 || i > PtrL->Last + 1) // 此时给定的位置 i 不合法
{
cout << "The location is not legal.";
return;
}
for (j = i; j <= PtrL->Last; j ++ )
PtrL->Data[j - 1] = PtrL->Data[j];
PtrL->Last -- ; // 挪完不要忘了把最后一个元素的位置也往前挪一个
return;
}二、链式存储
- 简单理解就是把每个数据分别存在一个方块里,然后用线(也就是指针)把这些方块串起来
1. 结构体定义
typedef struct LNode *List;
struct LNode{
ElementType Data; // 存这个方块里的数
List Next; // 这个指针存的是下一个方块的位置
};2. 求表长
思路: 就是很简单的遍历一遍…int Length(List PtrL)
{
List p = PtrL; // p在表头位置
int j = 0; // 表长初始化为0
while (p) // 只要p不为NULL就继续循环
{
p = p->Next;
j ++; // 表长++
}
return j;
}3. 查找元素
思路: 很显然就是遍历单链表(1)查找指定的数值 X
List Find(ElementType X, List PtrL)
{
List p = PtrL; // p指向表头
while (p != NULL && p->Data != X)
p = p->Next;
return p; // 找到了就会返回X所在的指针,没找到正好会返回NULL
}(2)查找指定的位置 K
List FindKth(int K, List PtrL)
{
List p = PtrL; // p指向表头
int i = 1; // 表示目前正在遍历第 i 个位置
while (p != NULL && i < K)
{
p = p->Next;
i ++;
}
if (i == K) return p; // 找到返回该位置的指针
else return NULL; // 找不到返回NULL
}4. 插入元素
在线性表 PtrL 中插入元素 X 到第 i 个位置
思路: 先找到要插入位置的前一个位置(也就是第 i - 1 个位置),把这个新结点的 Next 指针指向前一个结点的 Next ,然后再将前一个结点的 Next 指向这个新结点,就完成啦~
List Insert(ElementType X, int i, List PtrL) |
5. 删除元素
在线性表 PtrL 中插入第 i 个元素
思路: 找到被删除元素的前一个位置,让前一个位置的 Next 指向被删除元素的 Next ,释放掉被删除元素,完成~
List Delete(int i, List PtrL) |
三、 顺序存储和链式存储的比较
- 顺序存储
- ==需要完整连续的一片空间存储==
- 可以在 O(1) 的时间复杂度内访问查找
- 插入删除效率低
- 大小固定,不能随意拓展
- 链式存储
- 内存利用率高,==不需要连续的空间存储==
- 查找访问效率低,需要从表头开始遍历
- 插入删除方便
- 大小不固定,可以随意拓展
本博客所有文章除特别声明外,均采用 CC BY-NC-SA 4.0 许可协议。转载请注明来自 Texcavator 的秘密基地!
评论