• 内部排序 明


    2013-01-23

     摘要:内部排序,包括直接插入、冒泡、快速、简单选择,堆排序。

    1 插入排序

     基本思想:将一个记录插入到以排好序的有序表中,从而得到一个新的、记录数增1的有序表。

    1.1 直接插入排序

     

    图1 直接插入排序

    View Code
     1 public static void InsertSort(int[] arr)
     2         {
     3             int i, j;
     4             int temp;
     5             for (i = 1; i < arr.Length; i++)
     6             {
     7                 temp = arr[i];
     8                 for (j = i - 1; j >= 0 && temp < arr[j]; j--)
     9                 {
    10                     arr[j + 1] = arr[j];
    11                 }
    12                 arr[j + 1] = temp;
    13             }
    14         }

    2 快速排序

     快速排序时基于“交换”进行排序的方法。

    2.1 冒泡排序

     基本思想:1)第一个和第二个比较,若逆序(First>Second),交换。然后进行第二个和第三个,以此类推,直到n-1和n个。这样,第一轮就把最大的“沉”到“底部”。

                   2)然后,第二轮比较前n-1个就行,以此类推,得到有序表。

     

    图2 冒泡排序

    View Code
     1 //采用自上向下扫描
     2         public static void BubbleSort(int[] arr)
     3         {
     4             int i, j;
     5             int temp;
     6             for (i = arr.Length - 1; i > 0; i--)
     7             {
     8                 for (j = 0; j < i; j++) //对当前无序区R[0..n-i]自下向上扫描
     9                 {
    10                     if (arr[j] > arr[j + 1])
    11                     {
    12                         temp = arr[j + 1];
    13                         arr[j + 1] = arr[j];
    14                         arr[j] = temp;
    15                     }
    16                 }
    17             }
    18         }

    2.2 快速排序

     基本思想:1)通过一趟排序把待排记录分割成独立的两部分,前一部分都比某个记录效,后一部分都比某个记录大

          2)对前一部分和后一部分按1)再分区,直到整个序列有序。

    图3 快速排序

    View Code
     1 public static void QuickSort(int[] arr)
     2         {
     3             QSort(arr, 0, arr.Length - 1);
     4         }
     5 
     6         public static void QSort(int[] arr, int low, int high)
     7         {
     8             if (low < high)
     9             {
    10                 int pivotLoc = Partition(arr, low, high);
    11                 QSort(arr, low, pivotLoc - 1);
    12                 QSort(arr, pivotLoc + 1, high);
    13             }
    14         }
    15 
    16         public static int Partition(int[] arr, int low, int high)
    17         {
    18             int pivot = arr[low];
    19             while (low < high)
    20             {
    21                 while ((high > low) && arr[high] >= pivot) --high;
    22                 arr[low] = arr[high];
    23                 while ((low < high) && (arr[low] <= pivot)) ++low;
    24                 arr[high] = arr[low];
    25             }
    26             arr[low] = pivot;
    27             return low;
    28         }

    3 选择排序

    基本思想:每一趟在最后的n-i+1(i=1,2,...,n-1)中取最小的记录作为有序表的第i个记录。

    3.1 简单选择排序

     

    图4 简单选择排序

    View Code
     1 public static void SelectSort(int[] arr)
     2         {
     3             int i, j;
     4             int minLoc;
     5             int temp;
     6             for (i = 0; i <= arr.Length - 1; i++)
     7             {
     8                 minLoc = i;
     9 
    10                 for (j = i + 1; j <= arr.Length - 1; j++)
    11                     if (arr[j] < arr[minLoc]) minLoc = j;
    12 
    13                 if (minLoc != i)
    14                 {
    15                     temp = arr[i];
    16                     arr[i] = arr[minLoc];
    17                     arr[minLoc] = temp;
    18                 }
    19             }
    20         }

    3.2 堆排序

    堆的定义

    图5 堆的定义

    我们可以吧这个序列看成一个二叉树,可得, 1)最大堆的根节点最大,2)上层总比下层大

    View Code
     1 public static void HeapSort(MyArr arr)
     2         {
     3             int i; int r;
     4             for (i = arr.Length / 2; i > 0; --i)
     5             {  //把H.r[1...H.length]建成大顶堆
     6                 HeapAdjust(arr, i, arr.Length - 1);
     7             }
     8             for (i = arr.Length; i > 1; --i)
     9             {
    10                 //将堆顶记录和当前未经排序子序列H.r[1..i]中最后一个记录相互交换
    11                 r = arr[1]; arr[1] = arr[i]; arr[i] = r;
    12                 HeapAdjust(arr, 1, i - 1);  //将H.r[1..i-1]重新调整为大顶堆
    13             }
    14         }
    15 
    16         //小的放在下层
    17         public static void HeapAdjust(MyArr arr, int s, int m)
    18         {
    19             int rc = arr[s];
    20             for (int j = 2 * s; j <= m; j = 2 * j)
    21             {  //沿key较大的孩子结点向下筛选
    22                 if (j < m && arr[j] < arr[j + 1]) ++j; //j为key较大的记录的下标
    23                 if (rc >= arr[j]) break; //rc应插入在位置s上
    24                 arr[s] = arr[j]; s = j;
    25             }
    26             arr[s] = rc;   //插入
    27         }
    28 
    29         //因为以零开始的数组,对于堆栈不好操作,也容易误解,所以自定义数组,以1起始
    30         public class MyArr
    31         {
    32             int[] arr;
    33             public int this[int pos]
    34             {
    35                 get
    36                 {
    37                     return arr[pos - 1];
    38                 }
    39                 set
    40                 {
    41                     arr[pos - 1] = value;
    42                 }
    43             }
    44             public int Length
    45             {
    46                 get
    47                 {
    48                     return arr.Length;
    49                 }
    50             }
    51             public MyArr(int[] arr)
    52             {
    53                 this.arr = arr;
    54             }
    55         }

    4 客户端 

    View Code
     1 class Program
     2     {
     3         static void Main(string[] args)
     4         {
     5             //1 直接插入排序
     6             int[] sample = new int[] { 53, 27, 36, 15, 69, 42 };
     7             DisplayArray("Original Sequence is: ", sample);
     8             Sort.InsertSort(sample);
     9             DisplayArray("InsertSort Sequence is: ", sample);
    10             //2 冒泡排序
    11             sample = new int[] { 70, 30, 40, 10, 80, 20, 90, 100, 75, 60, 45 };
    12             DisplayArray("Original Sequence is: ", sample);
    13             Sort.BubbleSort(sample);
    14             DisplayArray("BubbleSort Sequence is: ", sample);
    15             //3 快速排序
    16             sample = new int[] { 49, 38, 65, 97, 76, 13, 27 };
    17             DisplayArray("Original Sequence is: ", sample);
    18             Sort.QuickSort(sample);
    19             DisplayArray("QuickSort Sequence is: ", sample);
    20             //4 简单选择排序
    21             sample = new int[] { 58, 23, 35, 10, 76, 12 };
    22             DisplayArray("Original Sequence is: ", sample);
    23             Sort.SelectSort(sample);
    24             DisplayArray("SelectSort Sequence is: ", sample);
    25             //5 堆排序
    26             Sort.MyArr arr = new Sort.MyArr(new int[] { 49, 38, 65, 97, 76, 13, 27, 49 });
    27             Console.Write("Original Sequence is: ");
    28             for(int m=1;m<arr.Length;m++)
    29                 Console.Write("{0}  ", arr[m].ToString());
    30             Sort.HeapSort(arr);
    31             Console.WriteLine();
    32             Console.Write("HeapSort Sequence is: ");
    33             for (int m = 1; m < arr.Length; m++)
    34                 Console.Write("{0}  ", arr[m].ToString());
    35 
    36             Console.Read();
    37         }
    38 
    39         public static void DisplayArray(string declare, int[] arr)
    40         {
    41             Console.Write(declare);
    42             for (int m = 0; m < arr.Length; m++)
    43                 Console.Write("{0}  ", arr[m].ToString());
    44             Console.WriteLine();
    45         }
    46     }

    5 各种内部排序比较

    排序方法 平均情况  最坏情况  辅助空间 
    直接插入排序 O(n2) O(n2) O(1)
    起泡排序  O(n2) O(n2) O(1)
    快速排序 O(nlogn)  O(n2) O(logn) 
    简单选择排序  O(n2)  O(n2) O(1)
    堆排序 O(nlogn)  O(nlogn)  O(1)
  • 相关阅读:
    jsgraphics插件图形库
    MySQL 基础知识
    第四天:任务开始——网络驱动
    第三天:软件著作权申请
    第二天:办公流程及软件安装
    第一天:products和一些感想
    IMX6Q RTC驱动分析
    PLATFORM设备驱动
    字符设备驱动以及杂项设备驱动
    C程序编译过程及优化选项介绍
  • 原文地址:https://www.cnblogs.com/Ming8006/p/2873993.html
Copyright © 2020-2023  润新知