链表作为一个基础数据结构,对数组的排序方式在链表中都可以实现。
先创建一个链表:
LinkList *creat(int n){
LinkList *head, *node, *end, *a;
head = malloc(sizeof(LinkList));
end = head;
for (int i = 0; i < n; i++) {
node = malloc(sizeof(LinkList));
scanf("%d", &node->score);
end->next = node;
end = node;
}
end->next = NULL;
a = head;
while (a->next != NULL) {
a = a->next;
printf("%d ", a->score);
}
puts("");
return head;
}
选择排序:
排序可以以数组的排序思想来解决:
void sort(LinkList *list) {
list = list->next;
if (!list)
return;
for (LinkList *pt = list; pt != NULL; pt = pt->next) {
LinkList *min = pt;
for (LinkList *pr = pt; pr != NULL; pr = pr->next) {
if (pr->score > min->score)
min = pr;
}
int t = min->score;
min->score = pt->score;
pt->score = t;
}
}
目前只会选择排序,以后更新。。。
链表的反序:
反序也有多种解法,一般常用的是迭代解法。
LinkList *reverse(LinkList *list) {
if (list == NULL || list->next == NULL) {//两个元素也没事;
return;
}
LinkList *p1 = list;
LinkList *p2 = list->next;
LinkList *p3 = p2->next;
p1->next = NULL;//头变尾部
while (p3) {//控制防止读到NULL
p2->next = p1;//中间反序
p1 = p2; //各往后读一位
p2 = p3;
p3 = p3->next;
}
p2->next = p1;//反序最后一个
list = p2;//返回中间元素,因为当p3读到NULL时,p2已经是最后一个元素了
return list;
}
这种解法有5步:
1. 链表判断是否有两个以上结点(必须条件)
2. 定义三指针分别指向前三个
3. 头指向null
4. 循环判断如果第三个不为空,则执行以下两步,第一步、反序中间、第二步、三指针从p1开始顺序往后移动一个单位
5. 最后再反序中间一次,然后将中间返回
递归解法:
递归算法由于涉及到递归所以一般人难以理解。
LinkList *ReverseList(LinkList *node){
if (!node || !node->next) {//防止空链表和只有一个元素链表
return node;
}
LinkList* p1 = node->next;//p1指向第二个元素
LinkList* p2 = ReverseList(p1);//递归,p2最后等于尾部元素,尾部元素到成头部;p2也就是第二个,递归回来就剩下p1没反序
p1->next = node; //p1反序
node->next = NULL; //node变成尾部元素指向NULL
return p2;
}
清空链表的元素
清空链表就是只保留头指针。
void clearlist(LinkList *list) {
LinkList *q, *p;
if (list == NULL) {
return;
}
p = list->next;
while (p->next != NULL) {
q = p->next;
free(p);//清空所有元素
p = q;
}
list->next = NULL;//把头指针指向NULL,空链表
}
求链表长度
int ListLength(LinkList *list) {
LinkList *p = list;
int k=0;
while(p!=NULL)
{
k++;
p=p->next;
}
return k;
}