计划更新23王道数据结构所有课后代码习题的实现,虽然考试写的一般都是伪代码,但是强迫症的我还是全部实现了一遍,仓库在这里
代码全部是用 C++ 写的,都可以编译运行,包含暴力解和最优解。
持续更新,目前更新进度:
- 线性表 14/14
- 链表 25/25
- 栈
- …
仅供参考! 会包含一些考试不让写的语法,可能也会有一些错误。
18
- 循环单链表结构体及创建函数(可跳过)
// 创建一个带头结点的循环单链表
LinkList createHeadList(vector<int> data) {
if (data.size() == 0) return NULL;
LNode* head = (LinkList)malloc(sizeof(LNode));
head->next = NULL;
LNode* p = head;
for (int i = 0; i < data.size(); i++) {
LNode* q = (LNode*)malloc(sizeof(LNode));
q->data = data[i];
q->next = NULL;
p->next = q;
p = q;
}
p->next = head; // 最后指向头指针
return head;
}
void printList(LinkList L) {
LNode *head = L->next;
while (head != L) {
cout << head->data << " ";
head = head->next;
}
puts("");
}
- 首先找到h1的尾结点
- 然后找到h2的尾结点指向h1头结点
- 时间复杂度O(len1+len2),也就是O(n),空间复杂度O(1)
void linkTwoLists(LinkList h1, LinkList h2) {
// 1.创建工作指针
LNode *p1 = h1->next, *p2 = h2->next;
// 2.找到h1的尾结点
while (p1->next != h1) {
p1 = p1->next;
}
// 3.链接h2
p1->next = p2;
// 4.找到h2的尾结点,指向h1
while(p2->next != h2) {
p2 = p2->next;
}
p2->next = h1;
}
19
- 遍历循环单链表,每循环一次查找一个最小结点(循环单链表,注意循环终止条件!)
- minp指向最小值结点,minpre指向其前驱
- 输出其值然后删除,循环结束后释放头结点
- 时间复杂度O(n2),空间复杂度O(1)
void delMin(LinkList L) {
// 1.创建工作指针,遍历
LNode *p, *pre, *minp, *minpre;
while (L->next != L) {
pre = L, p = L->next;
minpre = pre, minp = p;
// 2.找到最小值,记录其前缀
while (p != L) {
if (p->data < minp->data) {
minp = p;
minpre = pre;
}
pre = p;
p = p->next;
}
// 3.输出并释放最小值结点
cout << minp->data << ' ';
minpre->next = minp->next;
free(minp);
}
// 4.释放头结点
free(L);
}
- 每次删除最小值结点,我们只需要记录最小值前缀即可
- 每次都用
minpre->next
进行比较 - 时间复杂度O(n2),空间复杂度O(1)
void delMin2(LinkList L) {
// 1.只剩一个头结点时停止
while (L->next != L) {
LNode *minpre = L, *p = L->next;
// 2.找到最小值,记录其前缀
while (p->next != L) {
if (p->next->data < minpre->next->data)
minpre = p;
p = p->next;
}
// 3.输出并释放最小值结点
cout << minpre->next->data << ' ';
LNode *del = minpre->next;
minpre->next = del->next;
free(del);
}
// 4.释放头结点
free(L);
}
- 如果只考虑输出的话,有一个取巧的方法
- 我们把链表的值取出来放在一个数组中排序输出
- 最后释放链表空间即可
- 用了cpp的
sort()
,所以时间复杂度O(nlog2n),空间复杂度O(n