数据结构与算法第一周(学习总结)

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;
}

  • 10
    点赞
  • 9
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值