• 快速排序的单链表实现


    在算法思想上,对于单链表的快速排序和对于数组的快速排序基本一致,但是同时也存在很大的区别,导致的原因我们也很容易明白,那就是单链表不支持像数组那样的方便的访问下标,也就是说我们无法对其进行从末尾向前遍历。所以我们将第一个链表第一个结点的值作为左轴,然后向右进行遍历,设置一个small指针指向左轴的下一个元素,然后比较如果比左轴小的话,使small指针指向的数据与遍历到的数据进行交换。最后将左轴元素与small指针指向的元素交换即可。之后就是递归。具体图解如下:

    下面附上代码:

    void quicksort(Linklist head, Linklist end){
    	if(head == NULL || head == end)             //如果头指针为空或者链表为空,直接返回
    		return ;
    	int t;
    	Linklist p = head -> next;                  //用来遍历的指针
    	Linklist small = head;
    	while( p != end){
    		if( p -> data < head -> data){      //对于小于轴的元素放在左边
    			small = small -> next;
    			t = small -> data;
    			small -> data = p -> data;
    			p -> data = t;
    		}
    		p = p -> next;
    	}
    	t = head -> data;                           //遍历完后,对左轴元素与small指向的元素交换
    	head -> data = small -> data;
    	small -> data = t;
    	quicksort(head, small);                     //对左右进行递归
    	quicksort(small -> next, end);
    }

    此外,对于链表,快排还有其他的思路。那就是将基准定下来后,遍历链表,选择比基准小的连成一个新的子表,选择比基准大的连成一个新的子表,然后将基准插入,进而再对两个子表进行递归快排

    void Quicksort(Linklist *head, Linklist end){
    	Linklist right;
    	Linklist *p1;
    	Linklist *p2;
    	Linklist flag;
    	Linklist old;
    	int num, left_num, right_num;
    	if(*head == end)
    		return ;
    	do{
    		flag = *head;                                                  //基准元素
    		p1 = head;                                                     //比基准元素小的链表
    		p2 = &right;                                                   //比基准元素大的链表
    		left_num = right_num = 0;                                      //记录两个链表长度的大小
    		for(old =(*head) -> next; old != end; old = old -> next){      //遍历当前函数中的链表
    			if(old -> data < flag -> data){                        //对于小于基准的元素,放在左链表中
    				left_num ++;
    				*p1 = old;
    				p1 = &(old -> next);
    			}
    			else{
    				++right_num;                                   //对于大于基准的元素,放在右链表中
    				*p2 = old;
    				p2 = &(old -> next);
    			}
    		}
    		*p2 = end;                                                     //封死右链表
    		*p1 = flag;                                                    //将基准插入在两个链表之间
    		flag -> next = right;
    		if(left_num > right_num){                                      //对长度更小的链表进行递归快排运算
    			Quicksort(&(flag -> next), end);
    			end = flag;
    			num = left_num;
    		}
    		else{
    			Quicksort(head, flag);
    			head = &(flag -> next);
    			num = right_num;
    		}
    	}while(num > 1);
    }

    对于链表中的快速排序暂时说这么多,但是实际上快排是不适合单链表的,应用归并排序效率更好


  • 相关阅读:
    String
    Xposed源码编译踩坑实录
    Hello 博客园
    HDU 1430 关系映射 + 打表 .
    HDU 1430 关系映射 + 打表 .
    hdu1043 经典的八数码问题 逆向bfs打表 + 逆序数
    hdu1043 经典的八数码问题 逆向bfs打表 + 逆序数
    hdu 1044 BFS(压缩图)+DFS
    hdu 1044 BFS(压缩图)+DFS
    hdu3338 最大流
  • 原文地址:https://www.cnblogs.com/chilumanxi/p/5136146.html
Copyright © 2020-2023  润新知