zoukankan      html  css  js  c++  java
  • 编程珠玑笔记排序

    首先来个插入排序

    #include <stdio.h>
    
    void swap(int *x, int *y)
    {
    	int t = *x;
    	*x = *y;
    	*y = t;
    }
    void insert_sort(int *x, int length)
    {
    	int i, j;
    	for (i = 1; i < length; i++)
    		for (j = i; j > 0 && x[j-1] > x[j]; j--)
    			swap(&x[j-1], &x[j]);
    }
    
    int main(void)
    {
    	
    	int i, a[] = {42, 20, 17, 13, 28, 14, 23, 15};
    	insert_sort(a, 8);
    	for (i = 0; i < 8;i++)
    	   printf("%4d", a[i]);		
    	return 0;
    }
    

    在第二个for循环中,总是给t赋予相同值x[i],可以将其移出第二个for循环

    void insert_sort(int *x, int length)
    {
    	int i, j;
    	for (i = 1; i < length; i++)
    	{
    		int t = x[i];
    		for (j = i; j > 0 && x[j-1] > t; j--)
    			x[j] = x[j-1];
    		x[j] = t;
    	}
    }

    一种简单的快速排序

    排序数组时,将数组不停分成两个小部分,进行递归排序,分别用l和u表示数组排序部分的下界和上界,递归结束条件是待排序部分的元素个数小于2.

    然后围绕某一值t对数组进行划分,重新组织x[a….b],并计算中间元素的下标m,使得所有<t在m左,所有>t在m右

    |a      <t         |m       >= t     |i            ?未处理部分            b|

    m = a -1;
    for i = [a, b]
    	if x[i] < t
    		swap(++m, i);
    void q_sort(int l, int u)
    {
    	if (l >= u)
    		return ;
           m = l;
           for (int i = l +1; i <= u; i++)
              if (x[i] < x[l])
                swap(++m, i);
           swap(m, l);
    	qsort(l, p -1);
    	qsort(p + 1, u);
    }

    从右侧划分,完整代码

    void qsort2(int l, int u)
    {
    	if (l >= u)
    		return;
    	m = i = u + 1;
    	do
    	{
      	  while (x[--i] < x[l]) ;	
     	     swap(i, --m);	
    	}
            while (i != l)
    	qsort2(l, m - 1);
    	qsort2(m + 1, u);
    } 
    
    

    当元素相同时,为最坏情况o(n*n),使用双向划分可解决问题,变为o(nlog(n))

    主循环中有两个循环,第一个内循环将i向右移过小元素,遇到大元素停止;第二个内循环向左移过大元素,遇到小元素停止。
    主循环测试这两个下标若交叉,则交换它们的值。
    void qsort3(int l, int u)
    {
    	if (l >= u)
    		return ;
    	int i = l, j = u + 1, t = x[l];
    	while (1)
    	{
    		while (x[j] > t) j--;
    		while (i <= u && x[i] < t) i++;
    		if (i > j)
    			break;
    		swap(i, j);
    	}
    	swap(l, j);
    	qsort3(l, j - 1);
    	qsort3(j + 1, u);
    }
     

    以上都是按照第一个元素进行划分,随机选择划分元素可得到更好的性能 swap(l, randint(l, u));.

    int bigrand()
    {
    	return RAND_MAX*rand() + rand();
    }
    
    int randint(int l, int u)
    {
    	return l + bigrand() % (u - l + 1);
    }

    对于任意n元输入数组,快速排序时间都正比于nlogn。

    快速排序会花费大量时间来排序很小数组,如果用插入排序累排序小数组,程序速会更快。

    void qsort4(int l, int u)
    {
    	if (u - l < cutoff)
    		return;
    	swap(l. randint(l, u));
    	int t = x[l], i = l, j = u + 1;
    	for (;;)
    	{
    		while (i <= u && x[i] < t) i++;
    		while (x[j] > t) j--;
    		if (x > j)
    			break;
    		swap(i, j);
    	}
    	swap(j, l);
    	qsort4(l, j - 1);
    	qsrt4(j + 1, u);
    }
    
    void test()
    {
          qsort4(0, length - 1)
          insert_sort(x, length);
    }
    0
  • 相关阅读:
    86. Partition List
    328. Odd Even Linked List
    19. Remove Nth Node From End of List(移除倒数第N的结点, 快慢指针)
    24. Swap Nodes in Pairs
    2. Add Two Numbers(2个链表相加)
    92. Reverse Linked List II(链表部分反转)
    109. Convert Sorted List to Binary Search Tree
    138. Copy List with Random Pointer
    为Unity的新版ugui的Prefab生成预览图
    ArcEngine生成矩形缓冲区
  • 原文地址:https://www.cnblogs.com/seebro/p/2472748.html
Copyright © 2011-2022 走看看