快速排序:
快速排序的主要思想是:
1)选定一个基准元素
2)经过一趟排序,将所有元素分成两部分
3)分别对两部分重复上述操作,直到所有元素都已排序成功
因为单链表只能从链表头节点向后遍历,没有prev指针,因此必须选择头节点作为基准元素。这样第二步操作的时间复杂度就为O(n)。由于之后都是分别对两部分完成上述操作,因此会将链表划分为lgn个段,因此时间复杂度为O(nlgn)
从中可以看出,快排实现也是先对数据进行一遍遍历找到关键值得位置,和数组不同的是数组可以从两端向中间靠拢,但是单向链表只能从一段开始,但用两个指针同样可以实现。
需要明白的一点是节点的指针就是我们在节点中定义的next指针,不要考虑的太多
//#include <iostream>
#include "stdio.h"
#include "stdlib.h"
//using namespace std;
//构造结点并初始化
typedef struct node
{
int val;
node * next;
node(int x):val(x),next(NULL){}
}mynode,*pmynode;
void swap(int* a,int * b)
{
int tmp = *a;
* a = *b;
* b = tmp ;
}
//定位
node *partion(node *pbegin ,node * pend)
{
if(pbegin ==pend ||pbegin->next ==pend)
return pbegin;
int mykey = pbegin ->val; //选择基准
node * p =pbegin ;
node* q =pbegin;
while(q != pend)
{
if(q->val< mykey )
{
p = p->next;
//这两种交换写法都是正确的
//swap( &(p->val) ,&(q ->val)); //小于则交换
swap( &p->val ,&q ->val); //小于则交换
}
q =q ->next;//否则一直往下走
}
swap(&p->val,&pbegin->val); //定位
return p;
}
void quick_sort(node *pbegin,node *pend)
{
if(pbegin ==pend ||pbegin->next ==pend)
return ;
node *mid =partion(pbegin,pend);
quick_sort(pbegin,mid);
quick_sort(mid->next,pend);
}
node *mysort(node *head,node *end)
{ //如果头结点为空,则直接跳出循环
//if(head ==NULL ||head -> next==NULL);
//return head;
quick_sort(head ,end);
return head;
}
int main()
{
node a(1);
node b(4);
node c(6);
node d(2);
node e(5);
node f(7);
a.next = &b;
b.next = &c;
c.next = &d;
d.next = &e;
e.next = &f;
//swap( & b->val ,& c->val);
pmynode head = & a;
printf("%d\n", head->val);
printf("%d\n", (&a)->val);
//printf("%d", &a->val);
//如果节点的指针不为空则打印节点
while(head)
{
printf("%d \t",head ->val);
head =head -> next;
}
printf("\n");
// pmynode head0 =mysort(head,&f);
pmynode head0 =mysort(&a,&f);
while(head0)
{
printf("%d \t",head0 ->val);
head0 =head0 -> next;
}
return 0;
}