排序复习(插眼)

数组操作

排序

选择排序

原理:选择一个下标,然后用这个下标对应的元素依次和后面的每一个元素进行比较

在这里插入图片描述

static void main(String[] args){
    //数组排序
	//1、选择排序
	//原理:选择一个下标,然后用这个下标对应的元素依次和后面的每一个元素进行比较
	int[] array = { 1, 2, 13, 46, 57, 67, 4 };
	Sort01(array);
	foreach (int item in array)
	{
    	Console.Write(item + ",");
	}
}

    //使用选择排序来对一个数组进行升序排序
static void Sort01(int[] array)
{
    //外层循环用来遍历需要和后面所有的元素比较的下标
    for (int i = 0; i < array.Length - 1; i++)
    {
        //内层循环的下标依次和外层的下标进行比较
        for (int j = i + 1; j < array.Length; j++)
        {
            //交换的条件
            if (array[i] > array[j])
            {
                //如果前面的元素大就交换元素
                int temp = array[i];
                array[i] = array[j];
                array[j] = temp;
            }
        }
    }
}
冒泡排序

原理:依次比较两个相邻的元素

//2、冒泡排序
#region
//原理:依次比较两个相邻的元素
int[] array = { 1, 2, 5, 3, 4 };

Sort02(array);
foreach (int item in array)
{
    Console.Write(item + ",");
}

//使用冒泡排序对数组进行升序排序
static void Sort02(int[] array)
{
    for (int i = 0; i < array.Length; i++)//循环的趟数
    {
        //每比较完一趟就一定会有一个较大的数被排好所以循环的条件是:j < array.Length - i - 1
        for (int j = 0; j < array.Length - i - 1; j++)//每趟循环的次数
        {
            if (array[j] > array[j + 1])
            {
                int temp = array[j];
                array[j] = array[j + 1];
                array[j + 1] = temp;
            }
        }
    }
}

交换排序

双层for循环,相邻位不断比较,每一轮筛选出最大数元素,在下了一轮将其排除在外,再进行新一轮的的筛选(冒泡排序是最简单的交换排序)。
时间复杂度为O(n²)

private void exchangeSort(int[]array)
{
  int demian=0;
  for(int i=1;i<array.Length;i++)
    {
       for(int j=0;j<array.Length-i;j++)
         {
           if(array[j]>array[j+1])
             {
               demian=array[j];
               array[j]=array[j+1];
               array[j+1]=demian;
             }
         }
    }
}
插入排序

排序思想:1.是将数组的首位元素作为已经排序好的数组
2.取出下一个元素,将其在排好序的从后往前进行扫描
3.找到比这个数小或等于这个数的,将这个数插在下个位置
4.重复2,3两个步骤,直到结束。

private void insertSort(int[]array)
{
   for(int i=1;i<array>length;i++)
   {
     int insertValue=array[i];//要准备插入的数
     int insertIndex=i-1;//前一个数的下标
     //条件满足说明还要继续寻找合适的位置
     while(insertIndex>=0 &&insertValue<array[insertIndex])
     {
       array[insertIndex+1]=array[insertIndex];//大于要插得数将其下标往后移
       insertIndex--;
     }
     //插入适合的位置
     array[insetIndex+1]=insertValue;
   }
}
希尔排序

每隔整数(sp)个数进行排序,即组内有序,当sp为1时,进行类似于插入排序,最终构造成有序数组。

//核心算法:
for(int i=0;i<array.Length-sp;i++)
{
	for(int j=i;j<array.Length-sp;j+=sp)
	{
		if(array[j]>array[j+sp])
		{
			demian=array[j];
			array[j]=array[j+sp];
			array[j+sp]=demian;
		}
	}
}
private void spSort(int[] array,int[]sp)
{
  for(int i=0;i<sp.Length;i++)
  {
  //这里的sp数组存储的是要间隔的数,数组里的数是从大到小的,列如{5,3,1}
  //创建这个spSort是为了方便,也可以在main函数里自己用不同的sp多次调用shellSort
    shellSort(array,sp[i]);
  }
}
//希尔排序主体
private void shellSort(int[]array,int sp)
{
  int demian=0;
  for(int i=0;i<array.Length-sp;i++)
  {
    for(int j=i;j<array.Length-sp;j+=sp)
    {
      if(array[j]>array[j+sp])
      {
        demian=array[j];
        array[j]=array[j+sp];
        array[j+sp]=demian;
      }
    }
  }
}
归并排序

归并思想:将若干个有序的数组合并成一个有序的数组,有两种合并思想
1.自下向上进行合并
2.自顶向下进行合并
(做法有点难讲,可百度)

private void mergeSort(int[] array,int first,int last)
{
try{
//first为表格的初始位置,last为表格的末尾位置
 if(first<last)
 {
    int mid=(first+last)/2;
    mergeSort(array,first,mid);//这里用到了递归的思想
    mergeSort(array,mid+1,last);
    mergeSortCore(array,first,mid,last);
 }
 }
catch(Expection ex)
{}
p
}
//归并排序核心部分
rivate void mergeSortCore(int[] array,int first,int mid,int last)
{
try{
 int indexA=first;//左边表格的初始下标
 int indexB=mid+1;//右边表格的初始下标
 int[] coreArray=new int[last+1];//重新建立一个空数组,数组长度与array相同
 int coreIndex=0;//空数组的下标
 while(indexA<=mid&&indexB<=last)
 {
 //当左右表格中有一个遍历完之后,就退出
   if(array[indexA]<=array[indexB])
   {
     coreArray[coreIndex++]=array[indexA++];
   }
   else(array[indexA]>array[indexB])
   {
     coreArray[coreIndex++]=array[indexB++]
   }
 }
 //剩余没有遍历完的填在coreArray后面
 while(indexA<=mid)
 {
   coreArray[coreIndex++]=array[indexA++];
 }
 while(indexB<=last)
 {
   coreArray[coreIndex++]=array[indexB++];
 }
 //将coreArray数组写入原数组
 for(int i=0;i<array.Length;i++)
 {
   array[i]=coreArray[i];
 }
 }
 catch(Exception ex)
{}
}
快速排序

快速排序的做法:在无序的数组中选择一个基准元素,使得在基准元素的左边都比基准元素小,右边都比基准元素大,基准元素不参加排序。快速排序是不稳定排序。

过程:
1.在无序数组中选择一个基准元素,命名为keyValue,数组的起始和末尾分别加一个指针i,j。
2.将i逐渐增大,直到找到大于keyValue的数为止。
3.将j逐渐增大,直到找到小于keyValue的数为止。
4.如果i<j的话,即两者之间的元素是大于1的,则array[i]与array[j]交换。

//快速排序
/// <summary>
        /// 快速排序
        /// </summary>
        /// <param name="array"></param>
        /// <param name="low"></param>
        /// <param name="high"></param>
        public static void QuickSort(int[] array,int low,int high)
        {
            //基线条件
            if (low >= high)
            {
                return;
            }

            //得到基准值
            int pivotIndex = QuickSortIndex(array, low, high);

            //进行递归
            QuickSort(array, low, pivotIndex - 1);
            QuickSort(array, pivotIndex + 1, high);
        }
        #endregion

        #region 快速排序的核心代码写法
        public static int QuickSortIndex(int[] array,int low, int high)
        {
            //设置一个基准值
            int pivote = array[low]; //9

            int left = low;//左指针  0
            int right = high;//右指针 8

            try//由于快速排序是一个不稳定的排序算法,这里用异常处理机制来预防代码出现异常
            {
                while (left < right)
                {
                    /*这里需要注意的是指针先从后往前进行一个移动 
                     这里的指针的移动顺序非常重要,指针的移动一定是要从后往前进行移动的,再进行从前往后移动的
                     在两个指针相碰的人位置退出while循环,同时将这个位置记录下来作为一个预先设定基准值的位置*/
                    while (left < right && array[right] >= pivote)
                    {
                        right--;
                    }
                    array[left] = array[right];

                    while (left < right && array[left] <= pivote)
                    {
                        left++;
                    }
                    array[right] = array[left];
                }
                //此处的left=right;
                //将此时的左右指针共同指向的位置赋予所设定的基准值
                array[left] = pivote;

                
            }
            catch
            {

            }
           return left;
        }
        #endregion 

数组查找

顺序查找

从数据的第一个元素开始,依次比较,直到找到目标数据或查找失败。

/*
1.从表中的第一个元素开始,依次与关键字比较。
2.若某个元素匹配关键字,则 查找成功。
3.若查找到最后一个元素还未匹配关键字,则 查找失败。
*/
public class Program {
    public static void Main(string[] args) {
        int[] array = { 10, 19, 21, 67, 99, 110, 920, 1000 };
        Console.WriteLine(SequentialSearch(array, 80));
        Console.ReadKey();
    }
    private static int SequentialSearch(int[] array, int key) {
        for (int i = 0; i < array.Length; i++)
            if (array[i] == key)
                return i;
        return -1;
    }
}
二分查找

前提条件:数组需要是排序的

原理:每次查找指定范围的中间值

int[] array = { 10, 19, 21, 67, 99, 110, 920, 1000 };
int index = -1;//表示查找到的元素的下标

//确定一个要查找的下标范围
int min = 0;
int max = array.Length - 1;
while (max >= min)//确保数组有元素 循环条件:极限状态下max = min 表示数组只有一个元素
{
    int mid = (min + max) / 2;

    if (array[mid] == 920)
    {
        index = mid;
        break;
    }
    else if (array[mid] > 920)
    {
        max = mid - 1;//查找范围缩小到一半,即范围改变成(0~中间值的前一个数)
    }
    else
    {
        min = mid + 1;//查找范围缩小一半,即范围改变成(中间值的后一个数~max)
    }
}
onsole.WriteLine(index);
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值