1.时间复杂度
O(n);最高次数(最坏情况)。
1.异或运算
#异或
N^0=N;
满足交换律,结合律
N1^N2^N3=N1^(N2^N3)
位运算的计算速度快于加减法
异或来换位
//异或换位
int a,b;
a=a^b;
b=a^b; //b=(a^b)^b;所以b等于a;
a=a^b; //a=a^b^(b=a); 即a=b;
//这个啊a,b的地址不能是一样。因为一个改变另外一个也会改变所以有问题
一.算法:
排序算法:
1.快速排序(O(n^2))
//快速排序
//快排思路:
//首次一个标记值,先找出这个值的正确位置,即把大于这个数的放到他右边小于他的数放到他的左边,
//即最后下标会和时就是这个标记值正确的位置
//注意点:
//1。这个是种递归,这个left和right的大小要时刻注意。不然会造成死循环
//2,用i,j来处理下标的移动,如果用left和right就会导致后面递归的出问题。
//3.用这个下标移动时,应该先移动右下标?
//如果全部相等,就进去,那么j一直减,知道j等于i跳出循环。
#include <stdio.h>
int a[100];
void quicksort(int left,int right)
{
int i, j, t, temp;
if (left > right)
return;
temp = a[left];
i = left;
j = right;
while (i != j)
{
while (a[j] >= temp && i < j)
j--;
while (a[i] <= temp && i < j) //因为这里第一个i一定满足,所以相当于i应该自动加了个1.
i++;
if (i < j)
{
t = a[i];
a[i] = a[j];
a[j] = t;
}
}
a[left] = a[i];
a[i] = temp;
quicksort(left, i - 1);
quicksort(i + 1, right);
}
int main() {
for(int i=0;i<10;i++)
scanf("%d", &a[i]);
quicksort(0, 9);
for(int i=0;i<10;i++)
printf("%d ", a[i]);
return 0;
}
2.桶排序:(浪费空间,得到速度)
#include <stdio.h>
int a[100001];
int main()
{
int N;
scanf("%d", &N);
for (int i = 0; i < N; i++)
{
int t;
scanf("%d", &t);
a[t]++;
}
for (int i = 0; i <100001; i++)
{
while (a[i]--)
printf("%d ", i);
}
return 0;
}
3.堆排序:
//这里有个heapify函数,这个函数是整个排序的核心
//heapify函数传参(指针,元素个数,节点下标)
//主要的作用是进行(把该节点i的数进行与下面的节点进行比较,
如果这个i节点不满足是这三个节点中最大的,则进行交换。经过这个函数后这个节点是大根堆。
//
void swap(int* a, int* b)
{
int t;
t = *a;
*a = *b;
*b = t;
}
void heapify(int arr[], int n, int i)
//n个元素,i节点 相当于i节点以下,恢复大根堆 向下滤,大的数向上交换
{
int largest = i;
int lson = i * 2 + 1;
int rson = i * 2 + 2;
if (lson < n && arr[largest] < arr[lson])
largest = lson;
if (rson < n && arr[largest] < arr[rson])
largest = rson;
if (largest != i)
{
swap(&arr[i],&arr[largest]);
heapify(arr, n, largest); //进行递归,把这个节点更改之后,下面的节点也要判断下,保持根的特性。
}
}
void heap_sort(int arr[], int index)
{
int i;
//建堆(建立堆特性)
for (i =(index-1)/2; i >= 0; i--) //找到第一个父节点,(下标-1)/2就是后面第一个父节点
heapify(arr, index+1, i);
//堆排序
for (i = index ; i > 0; i--) //这里大根堆里arr【0】是最大值,与最后一个元素交换,
然后把数组元素减一,相当于把最后一个除去(但实际上储存起来了)然后i进行减一进行循环。
{
swap(&arr[i], &arr[0]);
heapify(arr, i, 0);
}
}
int main()
{
int arr[100001];
int n;
scanf("%d", &n);
for (int i = 0; i < n; i++)
scanf("%d", &arr[i]);
heap_sort(arr, n-1);
for (int i = 0; i < n; i++)
printf("%d ", arr[i]);
return 0;
}
二.并查集
模板:
int fa[100]; //这里该数的祖宗
//初始化
void init(int a[],int n)
{
for(int i=1;i<n;i++)
fa[i]=i;
}
//找祖宗节点编号
int Find(int i)
{
if(fa[i]==i)return i;
else if(fa[i]!=i)
fa[i]=Find(fa[i]);
return fa[i];
}
//合并
void merge(int x,int y)
{
x=fa[x];
y=fa[y];
if(x!=y)
fa[x]=y;
}