这篇博客,仅供搞笑,并无任何不尊敬作者的意思,原书作者在学习上给了我很大帮助!
前言:我学习到链式存储结构,书中p37页,合并两个链表这一章节,它给了一段不超过15行的抽象代码~(微笑)
书图:
然后我们看看万恶之源:
对,就是这个,时间复杂度跟表长有关,等于O(La+Lb)
然后...给大家看看主函数:
int main()
{
if (!InitList(&La))
{
return ERROR;
}
if (!InitList(&Lb))
{
return ERROR;
}
int i, j;
printf("请输入La中的元素个数:");
scanf_s("%d", &i);
while (i)
{
InfoElem(La);
i--;
}
ListTraverse(La, PRINTF);
printf("\n请输入Lb中的元素个数:");
scanf_s("%d", &j);
while (j)
{
InfoElem(Lb);
j--;
}
ListTraverse(Lb, PRINTF);
MergeList_L(La, Lb, Lc,Maxcompare);
//ListTraverse(Lc, PRINTF);
system("pause");
return 0;
}
就那么点!!!不多吧???
但他妈的这自定义函数多啊,卧槽
各位大哥看图,看图就知道了,卧槽,我花了整整六个小时,才把完整算法完善好
但...有一说一,代码还是蛮整洁的....逻辑也清晰,但是这他妈的只是合并一个链表...我整整...写了300多行
卧槽,这书能把人逼疯......
最后附上完整的测试代码!!!期待大佬指出不足!!!:
#define OK 1
#define ERROR 0
#include<stdio.h>
#include<stdlib.h>
typedef int Status;
typedef struct LNode
{
int data;
struct LNode* next;
}*Link,*Position;
typedef struct
{
Link head, tail;
int len;
}LinkList;
LinkList La, Lb, Lc;
Status InitList(LinkList*);
Status MergeList_L(LinkList, LinkList, LinkList, int(*compare)(int, int));
Status InfoElem(LinkList);
Position GetLast(LinkList);
Position GetHead(LinkList);
Position NextPos(LinkList, Link);
int GetCurElem(Link);
int Maxcompare(int, int);
Status DelFirst(Link, Link*);
Status Append(LinkList, Link);
void FreeNode(Link);
Status ListTraverse(LinkList, Status(*visist)(Link));
Status PRINTF(Link);
int main()
{
if (!InitList(&La))
{
return ERROR;
}
if (!InitList(&Lb))
{
return ERROR;
}
int i, j;
printf("请输入La中的元素个数:");
scanf_s("%d", &i);
while (i)
{
InfoElem(La);
i--;
}
ListTraverse(La, PRINTF);
printf("\n请输入Lb中的元素个数:");
scanf_s("%d", &j);
while (j)
{
InfoElem(Lb);
j--;
}
ListTraverse(Lb, PRINTF);
MergeList_L(La, Lb, Lc,Maxcompare);
//ListTraverse(Lc, PRINTF);
system("pause");
return 0;
}
Status InitList(LinkList *L)
{
L->head = (Link)malloc(sizeof(struct LNode));
if (L->head == NULL)
{
return ERROR;
}
L->head->next = NULL;
L->len = 0;
return OK;
}
Status InfoElem(LinkList L)
{
Link node;
node = (Link)malloc(sizeof(struct LNode));
printf("请输入元素:");
scanf_s("%d", &node->data);
L.tail = GetLast(L);
node->next = L.tail->next;
L.tail->next = node;
L.tail = node;
L.len++;
return OK;
}
Position GetLast(LinkList L)
{
Link last;
last = L.head;
while (last->next != NULL)
{
last = last->next;
}
return last;
}
Position GetHead(LinkList L)
{
return L.head;
}
Position NextPos(LinkList L, Link p)
{
if (p->next == NULL)
{
return 0;
}
return p->next;
}
int GetCurElem(Link p)
{
return p->data;
}
int Maxcompare(int a, int b)
{
if (a <= b)
{
return 0;
}
return 1;
}
Status DelFirst(Link h, Link* s)
{
Link q;
q = h->next;
h->next = q->next;
q->next = NULL;
*s = q;
return OK;
}
Status Append(LinkList L, Link s)
{
Link q;
q = L.head;
while (q->next != NULL)
{
q = q->next;
}
q->next = s;
L.tail = s;
}
void FreeNode(Link q)
{
free(q);
q = NULL;
}
Status ListTraverse(LinkList L, Status(*visist)(Link))
{
printf("开始观察:");
Link q = L.head->next;
while (q != NULL)
{
if (!(visist(q)))
{
return ERROR;
}
else
{
q = q->next;
}
}
}
Status PRINTF(Link q)
{
printf("%d ", q->data);
return OK;
}
Status MergeList_L(LinkList La, LinkList Lb, LinkList Lc, int(*compare)(int, int))
{
Link ha, hb, pa, pb, q, pc;
int a, b;
if (!InitList(&Lc))
{
return ERROR;
}
ha = GetHead(La);
hb = GetHead(Lb);
pa = NextPos(La, ha);
pb = NextPos(Lb, hb);
int i = 0;
while (pa && pb)
{
i++;
a = GetCurElem(pa);
b = GetCurElem(pb);
if (((*compare)(a, b) <= 0))
{
printf("pa:第%d次:%d\n", i, pa->data);
DelFirst(ha, &q);
Append(Lc, q);
pa = NextPos(La, ha);
}
else
{
printf("\n");
printf("pb第%d次:%d\n", i, pb->data);
DelFirst(hb, &q);
Append(Lc, q);
pb = NextPos(Lb, hb);
}
}
if (pa)
{
Append(Lc, pa);
printf("pb第%d次:%d\n", i+1, pa->data);
}
else
{
Append(Lc, pb);
printf("pb第%d次:%d\n", i+1, pb->data);
}
pc = Lc.head->next;
printf("\n\nLc:");
ListTraverse(Lc, PRINTF);
FreeNode(ha);
FreeNode(hb);
return OK;
}
不过,可能是我屏幕小吧
咋一看也没多少....
哈哈哈哈哈哈
就是完善完后挺开心的真的,对于线性表:顺序表,动态顺序表,静态链式表,动态单链,动态双链,循环链表
都有很大的提升~
但是!!!!!!
上边的所有操作都是基于单链上完成的...
疑惑:我有必要再写个双循环链嘛....感觉挺麻烦,不知道有没有必要....期待大佬回答!!!