排序算法C++实现

排序

文章目录

      • 冒泡排序
      • 选择排序
      • 插入排序
      • 快速排序
      • 希尔排序
      • 归并排序
      • 堆排序
      • 基数排序

排序算法C++实现_第1张图片

冒泡排序

void BubbleSort(int *num, int length)
{
	int flag; //标记位,如果在一趟中未发生交换,则已经排序完成
	for (int i = 0; i < length - 1; i++) //表示趟数
	{
		flag = 0;
		for (int j = 0; j < length - i - 1; j++)
		{
			if (num[j] > num[j + 1])
			{
				flag = 1;
				num[j] = num[j] ^ num[j + 1];
				num[j + 1] = num[j] ^ num[j + 1];
				num[j] = num[j] ^ num[j + 1];
			}
		}
		if (flag == 0)
		{
			break;
		}
	}
}

选择排序

void SelectSort(int *num, int length) 
{
	for (int i= 0; i < length; i++)
	{
		int mindex = i;
		for (int j = i + 1; j < length; j++)
		{
			if (num[j] < num[mindex])
			{
				mindex = j;
			}
		}
		if (mindex != i)
		{
			num[i] = num[i] ^ num[mindex];
			num[mindex] = num[i] ^ num[mindex];
			num[i] = num[i] ^ num[mindex];
		}
	}
}

插入排序

void InsertSort(int *num, int length)
{
	if (num == NULL || length <= 0)
	{
		return;
	}
	//j表示已经排序好的数组的末尾元素
	for (int i = 0; i < length - 1; i++)
	{
		for (int j = i + 1; j > 0; j--)
		{
			if (num[j] < num[j - 1])
			{
				num[j] = num[j] ^ num[j - 1];
				num[j-1] = num[j] ^ num[j - 1];
				num[j] = num[j] ^ num[j - 1];
			}
			else 
			{
				break;
			}
		}
	}
}
void InsertSort(int arr[],int nLength)
{
    int j;//有序数组的最后位置
    int i;//无序数组的第一个
    int temp;

    if(arr == NULL || nLength <=0)return;

    for(i = 1;i=0)
        {
            //将前一个元素向后移动 
            arr[j+1] = arr[j];
            j--;
        }

        //将元素放入其对应位置
        arr[j+1] = temp;
    }

}

快速排序

void QuickSort(int arr[], int left, int right)
{
	if (left >= right)
	{
		return;
	}
	int i=left;
	int j = right;
	int key = arr[left];//基准,以最左边的作为基准
	while (i < j)
	{
		while (i < j&&arr[j] >= key) //从右向左找第一个小于key的值
		{
			j--;
		}
		if (i < j)
		{
			arr[i] = arr[j];
			i++;
		}
		while (i < j && arr[i] < key)//从左向右找第一个大于key的值
			i++;

		if (i < j) {
			arr[j] = arr[i];
			j--;
		}
	}
	arr[i] = key;
	QuickSort(arr, left, i - 1);
	QuickSort(arr, i + 1, right);
}
private static void quickSort(int[] arr, int low, int high) {

        if (low < high) {
            // 找寻基准数据的正确索引
            int index = getIndex(arr, low, high);

            // 进行迭代对index之前和之后的数组进行相同的操作使整个数组变成有序
            quickSort(arr, 0, index - 1);
            quickSort(arr, index + 1, high);
        }

    }

    private static int getIndex(int[] arr, int low, int high) {
        // 基准数据
        int tmp = arr[low];
        while (low < high) {
            // 当队尾的元素大于等于基准数据时,向前挪动high指针
            while (low < high && arr[high] >= tmp) {
                high--;
            }
            // 如果队尾元素小于tmp了,需要将其赋值给low
            arr[low] = arr[high];
            // 当队首元素小于等于tmp时,向前挪动low指针
            while (low < high && arr[low] < tmp) {
                low++;
            }
            // 当队首元素大于tmp时,需要将其赋值给high
            arr[high] = arr[low];

        }
        // 跳出循环时low和high相等,此时的low或high就是tmp的正确索引位置
        // 由原理部分可以很清楚的知道low位置的值并不是tmp,所以需要将tmp赋值给arr[low]
        arr[low] = tmp;
        return low; // 返回tmp的正确位置
    }

希尔排序

在要排序的一组数中,根据某一增量分为若干子序列,并对子序列分别进行插入排序。
然后逐渐将增量减小,并重复上述过程。直至增量为1,此时数据序列基本有序,最后进行插入排序。

void ShellSort(int arr[], int len)
{
	int temp = 0;
	int increase = len;
	if (arr == NULL || len <= 0)return;
	while (true)
	{
		increase = increase / 2;
		for (int k = 0; k < increase; k++)//根据定长分为若干序列,k表示每一组的起始位置
		{
			for (int i = k+increase; i k; j -= increase)
				{
					if (arr[j] < arr[j - increase])
					{
						arr[j] = arr[j] ^ arr[j - increase];
						arr[j - increase] = arr[j] ^ arr[j - increase];
						arr[j] = arr[j] ^ arr[j - increase];
					}
					else
					{
						break;

					}
				}
			}
			
		}
		if (increase == 1)
		{
			break;
		}
	}
}
public static void shellSort(int[] arrays) {
        //增量每次都/2
        for (int step = arrays.length / 2; step > 0; step /= 2) {

            //从增量那组开始进行插入排序,直至完毕
            for (int i = step; i < arrays.length; i++) {

                int j = i;
                int temp = arrays[j];

                // j - step 就是代表与它同组隔壁的元素
                while (j - step >= 0 && arrays[j - step] > temp) {
                    arrays[j] = arrays[j - step];
                    j = j - step;
                }
                arrays[j] = temp;
            }
        }
    }
void ShellSort2(int arr[], int len)
{
	int temp;//保存无序数组的第一个
	int k;
	for (int step = len / 2; step>0; step/=2) //step表示增量
	{
		//每一组开始插入排序
		for (int i = 0; i < step; i++) //i表示每一组的最后一个元素
		{
			for (int j = i + step; j < len; j += step)//j表示无序数组的第一个
			{
				k = j - step;//有序数组的最后一个
				temp = arr[j];//无序数组的第一个
				while (arr[k] > temp&&k >= i) 
				{
					arr[k + step] = arr[k];
					k -= step;
				}
				arr[k + step] = temp;

			}
		}
	}
}

归并排序

void MergeArray(int arr[], int left, int mid, int right)
{
	std::cout << left << " " << mid << " " << right << std::endl;
	
	int *temp = new int[right - left + 1];//临时数组
	int leftindex = left;
	int rightindex = mid + 1;
	int tempindex = 0;
	while (leftindex <= mid && rightindex <= right)
	{
		temp[tempindex++] = arr[leftindex] < arr[rightindex] ? arr[leftindex++] : arr[rightindex++];
	}
	std::cout << leftindex << " " << rightindex << " " << tempindex << std::endl;
	while (leftindex <= mid)
	{
		temp[tempindex++] = arr[leftindex++];
	}
	while (rightindex <= right)
	{
		temp[tempindex++] = arr[rightindex++];
	}
	Print(temp, right - left + 1);
	for (int i = left, tempindex =0; i <=right; i++, tempindex++)
	{
		arr[i] = temp[tempindex];
	}
	delete[]temp;
}
void MergeSort(int arr[], int left,int right)
{
	if (left < right)
	{
		int mid = (left + right) >> 1;
		MergeSort(arr, left, mid);
		MergeSort(arr, mid + 1, right);
		
		MergeArray(arr, left, mid, right);
	}
	
}

堆排序

void AdjustHeap(int arr[], int i,int length)
{
	int temp = arr[i]; //待调整的堆顶元素
	for (int k = i * 2 + 1; k < length; k = 2 * k + 1)//2 * k + 1 表示下一个子堆
	{
		if (k + 1 < length && arr[k] < arr[k + 1])
		{
			k++;
		}
		if (arr[k] > temp)  //如果子节点大于父节点,将子节点值赋给父节点(不用进行交换);上一步已经使k指向最大的子节点
		{
			arr[i] = arr[k];
			i = k;
		}
		else
		{
			break;
		}
	}
	arr[i] = temp;
}
void HeapSort(int arr[], int length)
{
	//建堆
	for (int i = length / 2 - 1; i >= 0; i--)//length / 2 - 1 表示第一个非叶子结点的索引
	{
		AdjustHeap(arr, i, length);
	}
	//排序
	for (int j = length - 1; j > 0; j--)
	{
		arr[j] = arr[0] ^ arr[j];
		arr[0] = arr[0] ^ arr[j];
		arr[j] = arr[0] ^ arr[j];
		// 元素交换之后,毫无疑问,最后一个元素无需再考虑排序问题了。
		// 接下来我们需要排序的,就是已经去掉了部分元素的堆了,这也是为什么此方法放在循环里的原因
		// 而这里,实质上是自上而下,自左向右进行调整的
		AdjustHeap(arr, 0, j);
	}
}

基数排序


int GetFigure(int num, int k)
{
	//返回整型数字num第k位的数字是什么
	int tem = int(pow(10, k - 1));
	return (num / tem) % 10;
}
void Lsd_RadixSort(int arr[],int length,  int max)//arr是要排序的数组,max是数组中最大的数有几位
{
	int *count = new int[10];
	int *bucket = new int[length]; //桶
	//k表示第几位,1代表个位,2代表十位
	for (int k = 1; k <= max; k++)
	{
		for (int i = 0; i < 10; i++)
		{
			count[i] = 0;
		}

		//此循环用来统计每个桶中的数据的数量
		for (int i = 0; i < length; i++)
		{
			count[GetFigure(arr[i],k)]++;
		}
		//count[i]的个数修改为前i个箱子一共有几个数字
		for (int i = 1; i < 10; i++)
		{
			count[i] = count[i] + count[i - 1];
		}
		for (int i = length - 1; i >= 0; i--) 
		{      //重点理解
			int j = GetFigure(arr[i], k);
			bucket[count[j] - 1] = arr[i];  //count[j]为索引
			count[j]--;
		}

		//将桶中的数据取出来,赋值给arr
		for (int i = 0, j = 0; i < length; i++, j++)
		{
			arr[i] = bucket[j];
		}
	}
	//delete[]count;
	//delete[]bucket;
}

你可能感兴趣的:(数据结构和算法)