笔记链接补充
数据结构学习
[blog.csdn.net/zbw328/arti…]
c 排序算法 [www.runoob.com/cprogrammin…]
c语言 二进制 负数
[blog.csdn.net/qq_16209077…] 正数的反码和补码都与原码相同。 负数的反码为对该数的原码除符号位外各位取反。 负数的补码为对该数的原码除符号位外各位取反,然后在最后一位加1
左移 << 丢弃最高位,低位补0 右移 >> 正数高位补0,负数高位补1 =》(对于正数其实就是做/2)
其他理解
希尔排序(分组插入排序)理解
[www.jianshu.com/p/d730ae586…]
将数组分成多个组,在每个组中进行(直接)插入排序:
分组间隔 = length/2 -> 1
快速排序
用三值中值方法区一个区间的基准值
小于基准值的放在左边 大于基准值的放在右边 (方式:初始i=0 j=last 将i左移j右移,直到arr[i] >= 基准 arr[j]<=基准停下,将ij交换;ij继续移动,直到ij交错,即i>j停止)
再将左右两边再排序,直到区间足够小
[zhuanlan.zhihu.com/p/57436476]
理解各种排序的动画及对应代码 [visualgo.net/en/sorting]
插入排序 insertion sort 稳定
以第一个元素为有序序列的初始,在剩下的未排序序列中依次选取元素插入有序序列
插入方式:从后向前扫描寻找合适位置插入,直到无序序列没有元素为止
void insertion_sort(int arr[] ,int ten){
int i,j,temp;
for(i = 1;i<len; i++){
temp = arr[i];
j = i-1;
while(j>=0 && arr[j]>temp){
arr[j+1] = arr[j]; //将有序序列中比temp大的元素往后移一位
j- -;
}
arr[j+1] = temp;
}
}
希尔排序 shell sort
For gap => 分组排序,每一组进行插入排序
for i => 某一组内,要插进有序序列的值
for j => 某一组内,被即将插入的值比较的值(前部有序列表中的值)(从后向前)
void shell_sort(int arr[], int len){
int i,j,gap,temp;
for(gap = len >> 1; gap > 0; gap = gap>>1){ //右移等同于len/2
for(i = gap; i<len; i++){
temp = arr[i];
for(j = i-gap; j>=0 && arr[j] > temp; j -= gap){
arr[j+gap] = arr[j];
}
arr[j+gap] = temp;
}
}
}
冒泡排序 bubble sort
依次比较相邻元素把大的放到右边,i轮之后最大元素在末尾,下一轮比较前面n-i个
直至n-i=1,一共比较了n-1轮
Void bubble_sort(int arr[],int len){
for(i=0;i<len-1;i++){
for(j=0;j<len-1-i;j++){
if(arr[j]>arr[j+1]){
temp = arr[j];
arr[j] = arr[j+1];
arr[j+1] = temp;
}
}
}
}
选择排序 selection sort
每一轮在未排序序列中找出最小元素,放到有序序列(数组前部)的末尾
void selection_sort(int arr[],int len){
int i,j,temp;
for(i=0;i<len-1;i++){
int min = i;
for(j=i+1;j<len;j++){
if(arr[j]<arr[min]){
min = j
}
}
temp = ….. //交换arr[i] 和 arr[min]
}
}
归并排序 merge sort
分而治之的思想,类似二叉树(迭代或者递归)
分:将数组平分成两个子数组,子数组再平分成子数组,直到子数组只包含两个元素
治:将子数组从下到上各自排序再合并;合并时利用一个新的数组,将两个有序数组的元素依次比较按序填入
迭代方法
int min(int x, int y) {
return x < y ? x : y;
}
void merge_sort(int arr[], int len) {
int *a = arr; // a指针指向目标数组arr
int *b = (int*) malloc(len * sizeof(int)); //直接分配一个最终合并所需长度的数组,b指针指向该数组
int seg, start;
for (seg = 1; seg < len; seg += seg) {
//seg为步长 2^x = len => x=log2n
for (start = 0; start < len; (start += seg) + seg) {
//将子树两个一组(二叉树思想)依次比较合并
int low = start, mid = min(start + seg, len), high = min(start + seg + seg, len);
int k = low;
int start1 = low, end1 = mid;
int start2 = mid, end2 = high;
while (start1 < end1 && start2 < end2)
//将左右子树有序序列,逐个比较放入较小的值,直到某一边的全部放入
b[k++] = a[start1] < a[start2] ? a[start1++] : a[start2++];
//将剩下的还有没有放入合并数组的子树中的值依次放进去
while (start1 < end1)
b[k++] = a[start1++];
while (start2 < end2)
b[k++] = a[start2++];
}
// 修改指针指向 将该次合并的结果数组b与数组a交换
int* temp = a;
a = b;
b = temp; //将a的换给b之后,下一轮b直接开始从0修改值(即废弃原a的值)
}
if (a != arr) {
// 指向arr的是b指针; 将排序的最终结果放回arr
int i;
for (i = 0; i < len; i++)
b[i] = a[i];
b = a;
}
free(b);
}
快速排序 quick sort
递归方法
#include <stdlib.h>
#include <stdio.h>
#include <time.h>
/*使用快速排序的区间大小临界值,可根据实际情况选择*/
#define MAX_THRESH 4
typedef int ElementType;
/*元素交换*/
void swap(ElementType *a,ElementType *b)
{
ElementType temp = *a;
*a = *b;
*b = temp;
}
/*插入排序*/
void insertSort(ElementType A[],int N)
{
/*优化后的插入排序*/
int j = 0;
int p = 0;
int temp = 0;
for(p = 1;p<N;p++)
{
temp = A[p];
for(j = p;j>0 && A[j-1] > temp;j--)
{
A[j] = A[j-1];
}
A[j] = temp;
}
}
/*三数中值法选择基准*/
ElementType medianPivot(ElementType A[],int left,int right)
{
int center = (left + right)/2 ;
/*对三数进行排序*/
if(A[left] > A[center])
swap(&A[left],&A[center]);
if(A[left] > A[right])
swap(&A[left],&A[right]);
if(A[center] > A[right])
swap(&A[center],&A[right]);
/*交换中值和倒数第二个元素*/
swap(&A[center],&A[right-1]);
return A[right-1];
}
/*分区操作*/
int partition(ElementType A[],int left,int right)
{
int i = left;
int j = right-1;
/*获取基准值*/
ElementType pivot = medianPivot(A,left,right);
for(;;)
{
/*i j分别向右和向左移动,为什么不直接先i++?*/
while(A[++i] < pivot)
{}
while(A[--j] > pivot)
{}
if(i < j)
{
swap(&A[i],&A[j]);
}
/*交错时停止*/
else
{
break;
}
}
/*交换基准元素和i指向的元素*/
swap(&A[i],&A[right-1]);
return i;
}
void Qsort(ElementType A[],int left,int right)
{
int i = 0;
register ElementType *arr = A;
if(right-left >= MAX_THRESH)
{
/*分割操作*/
i = partition(arr,left,right);
/*递归*/
Qsort(arr,left,i-1);
Qsort(arr,i+1,right);
}
else
{
/*数据量较小时,使用插入排序*/
insertSort(arr+left,right-left+1);
}
}
/*打印数组内容*/
void printArray(ElementType A[],int n)
{
if(n > 100)
{
printf("too much,will not print\n");
return;
}
int i = 0;
while(i < n)
{
printf("%d ",A[i]);
i++;
}
printf("\n");
}
int main(int argc,char *argv[])
{
if(argc < 2)
{
printf("usage:qsort num\n");
return -1;
}
int len = atoi(argv[1]);
printf("sort for %d numbers\n",len);
/*随机产生输入数量的数据*/
int *A = malloc(sizeof(int)*len);
int i = 0;
srand(time(NULL));
while(i < len)
{
A[i] = rand();
i++;
}
printf("before sort:");
printArray(A,len);
/*对数据进行排序*/
Qsort(A,0,len-1);
printf("after sort:");
printArray(A,len);
free(A);
return 0;
}