using System.Collections;
using System.Collections.Generic;
using UnityEngine;
//编程中常用的排序算法:冒泡排序,选择排序,插入排序,快速排序等
public class SortScript : MonoBehaviour {
void Start () {
// InsertionSort();
//SelectSort();
int[] arr = { 23, 44, 66, 76, 98, 11, 3, 9, 7 };
Debug.Log("排序前:");
for (int i = 0; i < arr.Length; i++)
{
Debug.Log(arr[i]);
}
//QucikSort(arr,0,arr.Length-1);
QucikSort_new(arr, 0, arr.Length - 1);
Debug.Log("排序后的结果:");
for (int i = 0; i < arr.Length; i++)
{
Debug.Log(arr[i]);
}
}
/*
1,插入排序:是一种稳定的排序算法,适用于少量数据的排序,基本操作步骤:
将一个数据插入到已经排好序的有序数据中,从而得到一个新的,个数加1的有序数据,
插入排序将要排序的数据分成两部分,第一部分包含了数组的所有元素,但将最后一个
元素除外,第二部分只包含这一个元素,当第一部分排序后,再把最后一个元素插入到
此刻这些有序元素中。
*/
//插入排序算法
void InsertionSort()
{
Debug.Log("插入排序法");
int temp = 0;
int[] arr = { 23, 44, 66, 76, 98, 11, 3, 9, 7 };
Debug.Log("插入前的数列");
for (int i = 0; i < arr.Length; i++)
{
Debug.Log(arr[i]);
}
//开始排序
for (int i = 1; i < arr.Length; i++)
{
for (int j = i; j >0; j--)
{
if (arr[j]>arr[j-1])
{
temp = arr[j];
arr[j] = arr[j - 1];
arr[j - 1] = temp;
}
}
}
Debug.Log("插入后的数列");
for (int i = 0; i < arr.Length; i++)
{
Debug.Log(arr[i]);
}
}
/*
2,选择排序
每一趟从待排序的元素中选择最小(或最大)的一个元素,顺序放在已经排好序的数列的最后
直到待排序的元素排完,选择排序是不稳定排序
*/
void SelectSort()
{
int[] arr = { 23, 44, 66, 76, 98, 11, 3, 9, 7 };
Debug.Log("选择排序前的数列");
for (int i = 0; i < arr.Length; i++)
{
Debug.Log(arr[i]);
}
//排序
int temp = 0, pos = 0;
for (int i = 0; i < arr.Length-1; i++)
{
pos = i;
for (int j = i+1; j < arr.Length; j++)
{
if (arr[j]<arr[pos])
{
pos = j;
}
}
//第i个数与最小的数arr[pos]交换
temp = arr[i];
arr[i] = arr[pos];
arr[pos] = temp;
}
Debug.Log("选择排序后后的数列");
for (int i = 0; i < arr.Length; i++)
{
Debug.Log(arr[i]);
}
}
/*
冒泡排序
*/
void Selentmvc()
{
int[] arr = { 23, 44, 66, 76, 98, 11, 3, 9, 7 };
Debug.Log("排序前的数列");
for (int i = 0; i < arr.Length; i++)
{
Debug.Log(arr[i]);
}
//排序
int temp = 0;
for (int i = 0; i < arr.Length-1; i++)
{
for (int j = 0; j < arr.Length-1-i; j++)
{
if (arr[j]<arr[j+1])
{
temp = arr[j];
arr[j] = arr[j+1];
arr[j + 1] = temp;
}
}
}
Debug.Log("排序后的数列");
for (int i = 0; i < arr.Length; i++)
{
Debug.Log(arr[i]);
}
}
/*
4,快速排序
通过一趟排序将要排序的数组分成独立的两个部分,其中一部分的所有数据都比另一部分数据
都小(或大)然后按此方法再对两部分数据进行快速排序,整个排序的过程采用
递归的方式进行,依次来达到整个数列的有序进行,快速排序也是不稳定排序
*/
//每次排序返回,下次进行排序分割的下表
public int KeyValue(int [] a,int low, int height)
{
//记录数组的起始位置
int leftIndex = low;
//记录数组的结束位置
int rightIndex = height;
//记录关键值,通过为low下表对应的元素
int keyValue = a[low];
int temp = 0;
//当左侧动态下标小于右侧动态下标时
while (leftIndex < rightIndex)
{
//右侧动态下标减少,直到找到比关键值小的位置,停止
while (a[rightIndex] > keyValue && leftIndex < rightIndex)
{
rightIndex--;
}
//左侧动态下标增加,直到找到比关键值大的位置停止
while (a[leftIndex] <= keyValue && leftIndex < rightIndex)
{
leftIndex++;
}
//把左右侧动态下标所在的元素值进行交换
if (leftIndex<rightIndex)
{
temp = a[leftIndex];
a[leftIndex] = a[rightIndex];
a[rightIndex] = temp;
}
}
//相遇时,交换相遇值与关键值得位置
a[low] = a[rightIndex];
a[rightIndex] = keyValue;
return rightIndex;
}
void QucikSort(int[] a, int low, int heigh)
{
//记录关键值得下标
int keyPosition = 0;
if (low<heigh)
{
//得到数组分割的下标元素
keyPosition = KeyValue(a, low, heigh);
//以关键分割点为界限,分别对分割出来的两个部分数据采用递归的方式再次进行分割,直到要
//参与排序分割的数据的个数为1,及low和heigh的值相等时结束
QucikSort(a, low, keyPosition - 1);
QucikSort(a, keyPosition + 1, heigh);
}
}
void QucikSort_new(int[]a,int left, int right)
{
if (left<right)
{
int i = left;
int j = right;
int middle = a[(left + right) / 2];
while (true)
{
while (i < right && a[i] < middle)
{
i++;
}
while (j > 0 && a[j] > middle)
{
j--;
}
if (i == j)
{
break;
}
//a[i] = a[i] + a[j];
//a[j] = a[i] - a[j];
//a[i] = a[i] - a[j];
int temp = a[j];
a[j] = a[i];
a[i] = temp;
if (a[i] == a[j])
{
j--;
}
}
QucikSort_new(a, left, i);
QucikSort_new(a, i + 1, right);
}
}
}