计数排序
void jishupaixu(int arr[], int n)
{
int jishu[100];
int fuzhu[100];//由于直接在里面换的话会导致出错,所以要建立辅助数组
for (int i = 0;i < n;i++)
{
jishu[i] = 0;
}
for (int i = 1;i < n;i++)
{
for (int j = 0;j < i;j++)
{
if (arr[j] <= arr[i])
{
jishu[i]++;
}
else
{
jishu[j]++;
}
}
}
for (int i = 0;i < n;i++)//在元素中移动到正确的位置
{
fuzhu[jishu[i]] = arr[i];
}
for (int i = 0;i < n;i++)
{
cout << fuzhu[i] << " ";
}
cout << endl;
}
思路:
先给计数数组赋值,外层循环嵌套内层循环,每次比较。
然后要注意新建一个数组,按序号放进元素。
如果要把原数组返回的话,就再把辅助数组中的每个元素的值赋值给原数组即可。
因此该方法的时间复杂度是n*(n-1)/2+2n(加号左边的是比较的次数,右边的是赋值给新数组、新数组再赋值给原数组的复杂度)
改进的计数排序
void new_jishupaixu(int arr[], int n)
{
int jishu[100];
for (int i = 1;i < n;i++)//给计数数组赋初值
{
jishu[i] = 0;
}
for (int i = 1;i < n;i++)
{
for (int j = 0;j < i;j++)
{
if (arr[j] <= arr[i]) jishu[i]++;
else jishu[j]++;
}
}
for (int i = 0;i < n;i++)
{
if (i != jishu[i])
{
int t = jishu[i];
int temp = arr[i];
arr[i] = arr[t];
arr[t] = temp;
jishu[i] = jishu[t];
jishu[t] = t;
}
}
for (int i = 0;i < n;i++)
{
cout << arr[i] << " ";
}
cout << endl;
}
可能也不是叫改进,就是节约了内存空间,但是增加了交换步数。
但是我总是写错这个,原因就是一是忘了每个元素对应的data和jishu要一起交换,二是每次应该把jishu【i】单独用一个变量存起来,否则会造成后面换序号时候的混乱。
选择排序
void xuanzepaixu(int arr[], int n)
{
for (int j = 0;j < n-1;j++)
{
int x = arr_min(arr, j, n - 1);
int temp = arr[j];
arr[j] = arr[x];
arr[x] = temp;
}
for (int i = 0;i < n;i++)
{
cout << arr[i] << " ";
}
}
int arr_min(int arr[],int start,int end)
{
int min = start;//min为最小值的下标序号
for (int i = start+1;i < end + 1;i++)
{
if (arr[i] < arr[min]) min = i;
}
return min;
}
这种方法仍然是比较了(n-1)*n/2次,但是每次交换三次,因此时间复杂度为(n-1)*n/2+3n。
冒泡排序
void bubble(int arr[], int n)
{
for (int i = 0;i < n-1;i++)
{
for (int j = 0;j < n - i-1;j++)
{
if (arr[j] >arr[j + 1])
{
int temp = arr[j];
arr[j] = arr[j + 1];
arr[j + 1] = temp;
}
}
}
for (int i = 0;i < n;i++)
{
cout << arr[i] << " ";
}
}
和选择排序复杂度一样。
当然,我们不难发现计数排序、选择排序和冒泡排序,本质都是外层循环n-1次(选择排序徐第一个元素左边没有和它比的),里面比较第一次是比较n-1次,最后一次是比较1次,这样比较的复杂度就是n*(n-1)/2了,交换三次就加3n,当然,交换多少次和原始数据有关。
插入排序
void insert(int arr[], int n, int val)//n是指这个数组的长度,val是传入的值
{
int c=n-1;
for (int i = n - 1;i >= 0 && val < arr[i];i--)
{
arr[i + 1] = arr[i];
c = i;
}
arr[c] = val;
}
void insertpaixu(int arr[], int n)
{
int m_arr[100];
m_arr[0] = arr[0];
for (int i=1;i<n;i++)//一开始的时候,第一个元素组成数组,数组长度为i,从第二个元素开始往里面插入
{
insert(m_arr, i, arr[i]);
}
for (int i = 0;i < n;i++)
{
cout << arr[i] << " ";
}
cout << endl;
}
感觉老师ppt好像错了,得用数组的第一个元素建立一个新的数组,然后调用insert函数每次往里面插入。