数据结构之排序算法

这是我在学习数据结构的时候,写的一些简单代码,关于各种排序,查找算法,可以作为他人学习数据结构的时候参考用

,由于写的比较匆忙,难免有问题,如有问题,欢迎指正!


#include <algorithm>
#include <stack>

//插入排序
/*
对于每一个元素位置i,先查找他对于前面已排序的位置j,然后
再将j到i之间的数组往后移位,将j位置插入原来i位置的元素,是稳定算法
*/
void insertSort(int a[], int l)
{
	for (int i = 1; i < l; i++)
	{
		int j = 0;//j是插入的位置
		while (a[j]<a[i] && j<i)
		{//将<改为>,就是降序法
			j++;
		}
		int temp = a[i];
		for (int k = i-1; k >= j;k--)
		{
			a[k+1] = a[k];
		}
		a[j] = temp;
	}
}


//交换排序

void swap(int& a, int &b)
{
	int temp = a;
	a = b;
	b = temp;
}

void bubbleSort(int a[],int l)
{
	//执行l-1次冒泡排序
	for (int i = 0; i < l-1;i++)
	{
		int flag = false;
		for (int j = l-1; j > i ;j--)
		{
			if (a[j]<a[j-1])
			{
				swap(a[j], a[j-1]);
				flag = true;
			}
		}
		//if 判断必须放在第二层for之外
		if (flag == false)
		{
			return;
		}
	}
}

//快速排序
//第一种方法
void quickSort(int a[], int l, int h)
{
	int partion(int a[], int l, int h);
	if (l < h)
	{
		int  i = partion(a, l, h);
		quickSort(a, l, i - 1);
		quickSort(a, i + 1, h);
	}
}
//前后夹击
int partion(int a[], int l, int h)
{
	int t = a[l];
	while (l < h)
	{
		while (l < h && a[h] >= t)
		{
			h--;
		}
		a[l] = a[h];
		while (l < h && a[l] <= t)
		{
			l++;
		}
		a[h] = a[l];
	}
	a[l] = t;
	return l;
}


int partion3(int a[], int l, int h)
{
	int& t = a[l];
	while (l < h)
	{
		while (l < h && a[h] >= t)
		{
			h--;
		}
		while (l < h && a[l] <= t)
		{
			l++;
		}
		swap(a[l], a[h]);
	}
	swap(t,a[l]);
}


//一前一后法
int partion2(int a[], int l, int h)
{
	int t = a[h];
	int i = l - 1;
	for (int j = l; j < h;j++)
	{
		if (a[j]<=t)
		{
			i++;
			swap(a[i],a[j]);
		}
	}
	swap(a[i+1],a[h]);
	return i + 1;
}

//n个整数中最小的K个数
void getMinKNum(int a[], int n, int k)
{
	if (a==NULL || n<=0 || k>n )
	{
		return ;
	}
	int start = 0;
	int end = n - 1;
	int index = partion(a,0,n-1);
	while (index !=k-1)
	{
		if (index > k - 1)
		{
			end = index - 1;
			index = partion(a, start, end);
		}
		else
		{
			start = index + 1;
			index = partion(a, start, end);
		}
	}
}

//选择排序
void selectSort(int a[], int l)
{
	for (int i = 0; i < l;i++)
    {
		int t = l-1;
		for (int j = l - 1; j>i; j--)
		{
			t = a[t] > a[j - 1] ?  j-1: t;
		}
		swap(a[t], a[i]);
    }
}

//堆排序,利用大根堆,a[]从1开始存储
void heapSort(int a[], int l)
{
	extern void buildMaxHeap(int a[], int l);
	extern void AdjustDown(int a[], int k, int l);
	buildMaxHeap(a, l);
	for (int i = l; i > 1;i--)
	{
		swap(a[i],a[1]);
		AdjustDown(a,1,i-1);
	}
}

//对排序,最小的K个数,用大根堆,不能使用小根堆,小根堆最后一个元素不一定是最大值,大根堆的第一个元素一定是最大值;
//b[]为a[1]-a[k];
void minKNum(int a[],int b[],int l, int k)
{
	extern void buildMaxHeap(int a[], int l);
	extern void AdjustDown(int a[], int k, int l);
	buildMaxHeap(b, k);
	for (int i = k; i < l;i++)
	{
		if (a[i]>=b[1])
		{
			continue;
		}
		else
		{
			b[1] = a[i];
			AdjustDown(b,1, k);
		}
	}
}

//归并排序,需要辅助空间b[]
int* b = new int[k];
void merge(int a[],int start,int end,int mid)
{
	for (int k = start; k <= end;k++)
	{
		b[k] = a[k];
	}
	int k = start;
	int i = start;
	int j = mid + 1;
	for (; i <= mid&&j <= end;)
	{
		if (a[i]<a[j])
			a[k++] = b[i++];
		else
			a[k++] = b[j++];
	}
	//i==mid可以去掉,为了更易懂,不省略
	while (i==mid&&j<=end)
	{
		a[k++] = b[j++];
	}
	while (j==end&&i<=mid)
	{
		a[k++] = b[i++];
	}
}

void mergeSort(int a[], int l, int h)
{
	//有点像快排的递归
    if (l<h)
    {
		int mid = (l + h) / 2;
		mergeSort(a, l, mid);
		mergeSort(a, mid + 1, h);
		merge(a, l, h, mid);
    }
}

//合并两个链表
struct link
{
	int value;
	link* next;
};
void linkMerge(link* list1,link* list2,link* &list)
{
    if (list1==NULL)
    {
		list = list2;
    }
	if (list2==NULL)
	{
		list = list1;
	}
	link* temp=NULL;
	while (list1 != NULL&&list2 != NULL)
	{
		if (list1->value > list2->value)
		{
			if (temp == NULL)
				temp = list2;
			else
				temp->next = list2;
			list2 = list2->next;

		}
		else
		{
			if (temp == NULL)
				temp = list1;
			else
				temp->next = list2;
			list2 = list2->next;
		}
	}
	if (list1 == NULL)
		temp->next = list2;
	else
		temp->next = list1;
	list = temp;
}

//原地归并排序,不需要辅助空间


//查找
//顺序查找,查找第二大的数
int find(int a[], int l)
{
	int min = (-1)<<31;
	int max = a[0];
	int secMax = min;
	for (int i = 1; i < l;i++)
	{
		if (a[i]>max)
		{
			secMax = max;
			max = a[i];

		}
		else if (a[i]>secMax)
		{
			secMax = a[i];
		}
	}
	return secMax;
}

//折半查找,当且仅当有序下的数组,不适合链表
//有个难点,当数组中没有该元素,该怎么表达出来
//l是数组元素个数,不是末尾元素索引,这样就可以访问到a[l-1];
int find(int a[],int l,int key)
{
	int start = 0;
	int end = l;
	int mid = 0;
	while (start<end)
	{
		mid = (start + end) / 2;
		if (a[mid]>key)
		{
			end = mid-1;
			//最好要-1,否则会进入死循环;
		}
		else if (a[mid] < key)
		{
			start = mid+1;
		}
		else
			return mid;
	}
	return -1;
	//作为没有该元素的标记
}


  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值