王道数据结构伪代码实现——第二章 线性表
2.1 顺序表
2.1.1 顺序表的定义
#define MaxSize 50
typedef int ElemType;//顺序表中的元素类型
//静态分配
typedef struct {
ElemType data[MaxSize];
int length;//顺序表的当前长度
}Sqlist;
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
2.1.2 顺序表的插入
- 移动元素
- 插入元素
- 增加表长
bool ListInsert(Sqlist& L, int i, ElemType e) {
if (i<1 || i>L.length + 1) {
return false;
}
if (L.length >= MaxSize) {
return false;
}//判断插入是否合法
for (int j = L.length; j >= i; j--) {//插入时,考虑j的初值,因为插入时要从最后一个元素开始依次后移一位,所以游标从j=L.length开始往前移动
L.data[j] = L.data[j - 1];//考虑边界条件,当i=1时,j=1,最后将data[0]赋给data[1]便完成了所有元素的移动,所以j最小为1
}
L.data[i - 1] = e;//i为位序,在第i个位置上插入元素e,实际对应在数组中就是L.data[i-1]=e
L.length++;//元素个数+1
return true;
}
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 13
- 14
- 15
- 16
2.1.3 顺序表的删除
- 删除元素
- 移动元素
- 删减表长
bool ListDelete(Sqlist& L, int i, ElemType& e) {
if (i<1 || i>L.length) {
return false;
}
if (L.length == 0) {
return false;
}
e = L.data[i - 1];
for (int j = i; j < L.length; j++) {//删除时,考虑j的初值,因为删除时元素要从被删除的结点开始依次前移一位,所以j=i,游标从前往后移动
L.data[j - 1] = L.data[j];//考虑边界条件,j最大为L.length-1,即将最后一个位序的元素L.data[j]赋给L.data[j-1]
}
L.length--;
return true;
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 13
2.1.4 查找元素
- 按值查找:
int LocateElem(Sqlist L, ElemType e) {
for (int i = 0; i < L.length; i++) {
if (L.data[i] == e) {
return i + 1;
}
}
return 0;
}
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 按位序查找:
ElemType GetElem(Sqlist L, int i){
return L.data[i];
- 1
- 2
2.1.5 打印顺序表
void PrintList(Sqlist& L) {
for (int i = 0; i < L.length; i++) {
printf("%%3d", L.data[i]);
}
printf("
");
}
- 1
- 2
- 3
- 4
- 5
- 6
2.2 线性表的链式存储——单链表
2.2.1 单链表的定义
#define MaxSize 50
typedef struct LNode {
int data;
struct LNode* next;
}LNode, * LinkList;
- 1
- 2
- 3
- 4
- 5
- 6
2.2.2 建立单链表
- 头插法:每次插入的新结点都在头结点之后,因而是逆序
//头插法建立单链表 (逆向建立)
LinkList List_HeadInsert(LinkList& L) {
LNode* s;//每次使s指向新结点
int x;
L = (LinkList)malloc(sizeof(LNode));//创建头结点 为什么L是一个指针 因为LinkList& L定义了结构体指针
L->next = NULL;//初始化为空链表
scanf("%%d", &x);
while (x != 9999) {
s == (LNode*)malloc(sizeof(LNode));//创建新结点 s为 (LNode*)型指针 (强制类型转换)
s->data = x;//新结点中存元素
s->next = L->next;
L->next = s;//新结点完全插入表中
scanf("%%d", &x);
}
return L;
}
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 13
- 14
- 15
- 16
- 尾插法:每次插入的新结点都在尾结点之后,因而是正序
//尾插法建立单链表(正向建立)
LinkList List_TailInsert(LinkList& L) {
int x;
L = (LinkList)malloc(sizeof(LNode));
LNode* s, * r = L;//每次使s指向新结点,r为表尾指针,且尾指针要初始化指向头结点 (或写成LinkLinst s,r也可以)
scanf("%%d", &x);
while (x != 9999) {
s = (LNode*)malloc(sizeof(LNode));
s->data = x;
r->next = s;
r = s;//r每次都要指向新的表尾结点
scanf("%%d", &x);
}
r->next = NULL;//尾结点指针置空 很重要!
return L;
}
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 13
- 14
- 15
- 16
2.2.3 查找元素
- 按值查找
//按值查找结点值
LNode* LocateElem(LinkList L, int e) {
LNode* p = L->next;
while (p && p->data != e) {
p = p->next;//指针后移
}
return p;
}
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 按序号查找
//按序号查找结点值
LNode* GetElem(LinkList L, int i) {
int j = 1;
LNode* p = L->next;//j=1也就是位序为1时 对应的就是头指针
if (0 == i) {
return L;
}
if (i < 1) {
return NULL;
}
while (p && j < i) {
p = p->next;
j++;//指针每次后移 直到找到位序为i时对应的指针
}
return p;
}
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 13
- 14
- 15
- 16
2.2.4 头插法第元素e插入第i个位置
bool List_HeadInsert(LinkList L, int i,int e) {
LNode* p = GetElem(L, i-1);//先找到要插入位置的前驱节点
if (NULL == p) {
return false;
}
LNode* s = (LinkList)malloc(sizeof(LNode));
s->data = e;
s->next = p->next;
p->next = s;
return true;
}
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
2.2.5 删除第i个元素
bool ListDelete(LinkList L, int i) {
LNode* p = GetElem(L, i - 1);
if (NULL == p) {
return false;
}
LNode* q = p->next;//让q指向待删除元素
p->next = q->next;//断链
free(q);
return true;
}
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
2.2.6 打印单链表
求表长原理相同,遍历链表并设置一个length计数即可:
void PrintList(LinkList L) {
L = L->next;
while (L != NULL) {
printf("%%3d", L->data);
L = L->next;
}
printf("
");
}
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
2.3 双链表
2.3.1 双链表的定义
typedef struct DNode{
int data;
struct DNode* prior, * next;
}DNode, * DLinkList;
- 1
- 2
- 3
- 4
2.3.2 双链表的建立
- 头插法
//头插法建立双链表
DLinkList Dlist_head_insert(DLinkList& DL) {
DNode* s;
int x;
DL = (DLinkList)malloc(sizeof(DNode));
DL->next = NULL;
DL->prior = NULL;//初始化双链表头结点
scanf("%%d", &x);
while (x != 9999) {
s= (DLinkList)malloc(sizeof(DNode));
s->data = x;
s->next = DL->next;
if (DL->next != NULL) {
DL->next->prior = s;
}
s->prior = DL;
DL->next = s;
scanf("%%d", &x);
}
return DL;
}
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 13
- 14
- 15
- 16
- 17
- 18
- 19
- 20
- 21
- 22
- 尾插法
//尾插法建立双链表
DLinkList Dlist_tail_insert(DLinkList& DL) {
int x;
DL = (DLinkList)malloc(sizeof(DNode));//带头节点的链表
DNode* s, * r = DL;//r代表尾指针
DL->prior = NULL;
scanf("%%d", &x);
while (x != 9999) {
s = (DNode*)malloc(sizeof(DNode));
s->data = x;
r->next = s;
s->prior = r;
r = s;
scanf("%%d", &x);
}
r->next = NULL;
return DL;
}
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 13
- 14
- 15
- 16
- 17
- 18
2.3.3 按序号查找结点值
单/双链表查找结点,思路相同,都是设置指针和游标不断后移
//按序号查找结点值
DNode* GetElem(DLinkList DL, int i) {
int j = 1;
DNode* p = DL->next;
if (i == 0) {
return DL;
}
if (i < 1) {
return NULL;
}
while (p&&j<i) {
p = p->next;
j++;
}
return p;
}
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 13
- 14
- 15
- 16
2.3.4 新结点插入双链表第i个位置
//新结点插入双链表第i个位置
bool DListFrontInsert(DLinkList DL, int i, int e) {
DNode* p = GetElem(DL, i - 1);//查找要插入元素的前一个结点
if (NULL == p) {
return false;
}
DNode* s = (DLinkList)malloc(sizeof(DNode));
s->data = e;
//插入结点的关键四步
s->next = p->next;
p->next->prior = s;//要插入第i个位置,所以理解为默认第i个位置是有元素的,则无需考虑if (p.next != NULL)才要p->next->prior = s 的情况
s->prior = p;
p->next = s;
return true;
}
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 13
- 14
- 15
2.3.5 删除第i个结点
//删除第i个结点
bool DListDelete(DLinkList DL, int i) {
DNode* p = GetElem(DL, i - 1);//查找要删除元素的前一个结点
if (NULL == p)
{
return false;
}
DNode* q = p->next;
if (NULL == q)//删除的元素不存在
return false;
p->next = q->next;
if (q->next != NULL) {//删除时考虑是否是最后一个结点 当其不是最后一个结点时 q->next->prior = p才有意义
q->next->prior = p;
}
free(q);
return true;
}
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 13
- 14
- 15
- 16
- 17
2.3.6 打印双链表
void PrintDList(DLinkList DL)
{
DL = DL->next;
while (DL != NULL) {
printf("%%3d", DL->data);
DL = DL->next;
}
printf("
");
}
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
推荐阅读