第2章代码
第2章代码
数据结构期末不挂科课程
Ch2 线性表
*/
#include <algorithm> // for std::min
#include <cstdio>
/* 顺序表 */
// 顺序表数据结构
#define MAX_SIZE 1000
typedef struct List {
int *elem;
int length;
} List;
// 初始化顺序表
List Create() {
List L;
L.elem = new int[MAX_SIZE];
L.length = 0;
return L;
}
// 顺序表插入
void ListInsert(List &L, int i, int val) {
if ((i < 0) || (i > L.length))
return;
if (L.length == MAX_SIZE)
return;
for (int j = L.length; j >= i + 1; j--) L.elem[j] = L.elem[j - 1];
L.elem[i] = val;
++L.length;
}
// 顺序表删除
void ListDelete(List &L, int i) {
if ((i < 0) || (i > L.length - 1))
return;
for (int j = i; j <= L.length - 2; j++) L.elem[j] = L.elem[j + 1];
--L.length;
}
/* 单链表 */
// 单链表数据元素:学生
typedef struct {
char id[10];
int age;
double score;
} Student;
// 单链表数据结构
typedef struct LinkListNode {
Student student;
struct LinkListNode *next; // 指针域
} Node;
// 单链表新增, 返回值为插入后的链表首元素指针
Node *LinkListInsert(Node *head, int i, Student &s) {
// head为NULL或i为0意味着需要在链表头前面插入
// 直接使用s和原head创建该结点即可, 返回该结点指针
if (!head || i == 0) {
return new Node{s, head};
}
1
newNode->next = p->next; // 设置指针域
p->next = newNode; // 完成插入
return head;
}
// 单链表删除
Node *LinkListDelete(Node *head, int i) {
// 删除原本的链表首元素
if (!head || i == 0) {
Node *newHead = head->next;
if (head) {
delete (head);
}
return newHead;
}
// 删除其他元素: 先找到前驱结点
Node *p = head;
int j = 0;
while (p && j < i - 1) {
p = p->next;
++j;
}
// !p说明链表没有i-1位置元素, !p->next说明没有i位置元素,
// 这里利用了||的短路效应, 顺序不可调换
if (!p || !p->next) {
return head;
}
Node *n = p->next;
p->next = n->next;
delete (n);
return head;
}
/* 合并两个有序顺序表 */
void MergeTwoArray(List A, List B, List &C) {
C.elem = new int(A.length + B.length);
int ia = 0, ib = 0, ic = 0;
while (ia < A.length && ib < B.length) {
if (A.elem[ia] < B.elem[ib]) {
C.elem[ic++] = A.elem[ia++]; // 添加元素 + 移动游标
} else {
C.elem[ic++] = B.elem[ib++];
}
}
while (ia < A.length) {
C.elem[ic++] = A.elem[ia++];
}
while (ib < B.length) {
C.elem[ic++] = B.elem[ib++];
}
C.length = A.length + B.length;
}
/* 合并两个有序链表 */
Node *MergeTwoLinkList(Node *headA, Node *headB) {
Node *dummy = new Node; // 头结点
dummy->next = NULL; // 不关心头结点的值,只利用其指针域
Node *pa = headA, *pb = headB, *pc = dummy;
while (pa && pb) {
if (pa->student.age < pb->student.age) {
pc->next = pa; // 添加元素
pa = pa->next; // 移动游标
} else {
pc->next = pb;
pb = pb->next;
}
pc = pc->next; // 移动结果表的游标
}
if (pa) {
pc->next = pa;
} else {
pc->next = pb;
}
Node *res = dummy->next;
delete (dummy);
2
return res;
}
int main() {
Student students[] = {
{"001", 12, 78.5f},
{"002", 13, 80.f},
{"003", 15, 98.5f},
};
// 创建一个空链表
Node *list = NULL;
// 插入一些学生数据元素
for (int i = 0; i < 3; ++i) {
list = LinkListInsert(list, 0, students[i]);
}
// 遍历链表打出来看看
for (Node *p = list; p; p = p->next) {
printf("id:%s, age:%d, score:%.1f\n", p->student.id, p->student.age,
p->student.score);
}
printf("----------\n");
// 删除位于下标1位置(第2个)的元素再打印看看
list = LinkListDelete(list, 1);
for (Node *p = list; p; p = p->next) {
printf("id:%s, age:%d, score:%.1f\n", p->student.id, p->student.age,
p->student.score);
}
}