1、函数简介
基本的结构是
typedef struct ListNode *List;
typedef struct ListNode *Position;
struct ListNode
{
ElementType Element;
Position Next;
};
因为是使用了指针来实现,所以一定要注意改变链表过程中指针的变化,否则出现了野指针链表就废了。
然后使用时基本是用单链表,所以查找一个元素的开销很大,只能用循环来做,所以如果在时间卡的比较紧的时候可以换成数组来实现。
基本的函数实现(参考教材):
1、初始化
要注意这里的链表是有哨兵节点的
List initial()
{
List L=malloc(sizeof(struct ListNode));
L->Next = NULL;
return L;
}
2、测试
int IsEmpty(List L)
{
return L->Next == NULL;
}
int IsLast(Position P,List L)
{
return P->Next ==NULL;
}
3、查找一个元素
Position Find(ElementType X,List L)
{
Position p=L->Next;
while(p && p->Element!=X)
p=p->Next;
return p;
}
Position FindPrevious(ElementType X,List L)
{
Position p=L;
while(p->Next && p->Next->Element!=X)
p=p->Next;
return p;
}
4、删除
void Delete(ElementType X,List L)
{
Position p,tmp;
p=FindPrevious(X,L);
if(!IsLast(p,L))
{
tmp=p->Next;//注意保留指针
p->Next=tmp->Next;
free(tmp);
}
}
5、插入
void Insert(ElementType X,List L,Position p)
{
Position tmp=malloc(sizeof(struct ListNode));
tmp->Element=X;
tmp->Next=p->Next;
p->Next=tmp;
}
2、知识点
然后在课程中不会全部用到。
我常写的只有Find函数。编程过程中要注意的基本就是指针的问题
这部分的知识点就是单链表、双链表、循环链表,一些应用,至于游标实现,不会用到。
3、应用
应用包括三个:多项式、基数排序、多重表,前两个比较重要
1、多项式
简介一下结构吧,实现还是很简单的
typedef struct Node *PtrToNode;
struct Node
{
int Coefficient;
int Exponent;
PtrToNode Next;
};
typedef PtrToNode Polynomial;
2、基数排序
简单来说就是不断地用桶排序
输入整数,然后按照低位到高位的顺序(当然,高位到低位也不影响),按照个位放到个位桶中
0 | 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 |
0 | 1 | 512 | 343 | 64 | 125 | 216 | 27 | 8 | 729 |
接着从0到9号桶遍历,查看每个数字的十位,放入相应的十位桶中
0 | 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 |
0 1 8 | 512 216 | 125 27 729 | 343 | 64 |
最后再遍历每个桶,查看数字的百位,放到百位桶中
0 | 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 |
0 1 8 27 64 | 125 | 216 | 343 | 512 | 729 |
再遍历一次就得到了排序
顺带说一下桶排序,这是种很好、很高效的排序方式。
当使用链表或者是一种需要反复查找元素的情景时很适合使用,举个栗子:
一共有999个地址,但是数据一共有10000个,需要统计每个地址的个数并且按照个数从大到小排序
这里如果使用链表来实现就很麻烦,如果用数组记录出现过的地址及其个数,其共同点就是对每一个数据都要查询相应的地址是否出现过,出现过就计数,没出现过就建一个新的,时间复杂度很高
但是这里我们已经知道了总地址数有999个,所以这里使用桶排序是很方便的
至于要按照个数从大到小排序,可以参考基数排序的思路(反复使用桶排序分级排序)遍历统计地址个数的时候记录下最大的个数,然后从大到小遍历,个数与最大个数相等,就输出相应的地址(直接输出方便点,其实按基数排序的思路,应该是按照个数放到新的桶中)
简单画个表
111 | 222 | 333 | 444 | 555 |
1 | 2 | 1 | 2 | 5 |
先是最大个数为5
1 | 2 | 3 | 4 | 5 |
0 | 0 | 0 | 0 | 555 |
然后是4
1 | 2 | 3 | 4 | 5 |
0 | 0 | 0 | 0 | 555 |
3
1 | 2 | 3 | 4 | 5 |
0 | 0 | 0 | 0 | 555 |
2
1 | 2 | 3 | 4 | 5 |
0 | 444 222 | 0 | 0 | 555 |
1
1 | 2 | 3 | 4 | 5 |
333 111 | 444 222 | 0 | 0 | 555 |
这样就按基数排序的思路完成了计数和排序任务