аха7 удивительное дерево

Куча — волшебная расстановка приоритетов

Создайте минимальную кучу, по очереди удалите верхние значения элементов и реализуйте сортировку кучи от меньшего к большему.
Временная сложность сортировки кучи равна 0 (NlogN).
Куча — это полное бинарное дерево, в котором родительский узел больше или равен (меньше или равен) левому и правому дочерним узлам.

//堆排序-从小到大排序建立最小堆
#include<iostream>
#include<algorithm>
using namespace std;

int h[101];//存放堆的数组
int n;//存放堆的大小

//向下调整函数
void siftdown(int i) //传入需要向下调整的结点编号i
{
    
    
	int t, flag=0;//flag标记是否需要向下调整
	//当i结点至少有右结点且需要向下调整
	while( i*2<=n && flag==0 )
	{
    
    
		//判断i结点与左结点的关系,并用t记录较小的结点编号
		if( h[i] > h[i*2])
			t = i*2;
		else
			t = i;
		//如果i有右结点
		if( i*2+1 <= n )
		{
    
    
			if(h[t] > h[i*2+1])//如果右结点值更小,更新最小的结点编号
				t = i*2+1;
		}
		//如果最小结点编号!=i
		if( t != i)
		{
    
    
			swap(h[t],h[i]);
			i = t;
		}
		else
			flag = 1;
	}
}

//建立堆
void creat() 
{
    
    
	int i;
	//从最后一个非叶结点依次向上进行调整
	for( i=n/2; i>=1; i-- )
	{
    
    
		siftdown(i);
	 } 
}

//删除最小的元素
int deletemin()
{
    
    
	int t;
	t = h[1];//记录堆顶的元素值 
	h[1] = h[n];//将堆最后一个值赋值给堆顶元素 
	n--;//堆大小减一
	siftdown(1);//从堆顶向下调整建立最小堆
	
	return t;//返回之前记录的堆顶值 
 } 
 
int main()
{
    
    
	int num;
	scanf("%d", &num);
	
	for(int i=1; i<=num; i++)
	{
    
    
		scanf("%d", &h[i]);
	}
		
	n = num;
	
	creat();//建堆 
	
	for(int i=1; i<=num; i++)//从小到大输出堆顶值 
		printf("%d ", deletemin());
	
	return 0;
}

вставьте сюда описание изображения
Есть лучший метод для сортировки кучи: построить максимальную кучу и поменять местами h[1] и h[n] по очереди, в это время h[n] является самым большим элементом в массиве. После обмена h[1] необходимо уменьшить, чтобы сохранить характеристики кучи. Уменьшите размер кучи на единицу, то есть на n–, затем поменяйте местами h[1] и h[n] и уменьшите h[1]. Пока размер кучи не равен 1, в настоящее время массив h является отсортированным числом.

//堆排序-从小到大排序建立最大堆
#include<iostream>
#include<algorithm>
using namespace std;

int h[101], n;

void siftdown(int i)
{
    
    
	int t, flag=0;

	while(i*2<=n && flag==0)
	{
    
    
		if( h[i] < h[i*2] )
			t = i*2;
		else
			t = i;

		if( i*2+1 <= n )
		{
    
    
			if(h[t] < h[i*2+1])
				t = i*2+1;
		}

		if(t != i)
		{
    
    
			swap(h[t], h[i]);
			i = t;
		}
		else
			flag = 1;
	}
}

void creat()
{
    
    
	for(int i=n/2; i>=1; i--)
	{
    
    
		siftdown(i);
	}
}

//堆排序
void heapsort()
{
    
    
	while( n>1 )
	{
    
    
		swap(h[1], h[n]);
		n--;
		siftdown(1);
	}
}

int main()
{
    
    
	int num;
	scanf("%d", &num);
	
	for(int i=1; i<=num; i++)
		scanf("%d", &h[i]);
	n = num;
	
	creat();
	heapsort();
	
	for(int i=1; i<=num; i++)
		printf("%d ", h[i]);
	
	return 0; 
}

вставьте сюда описание изображения
Используйте сортировку кучей, чтобы найти k-е наибольшее или k-е наименьшее число в последовательности.

//求数列中第K小的数
#include<vector>
#include<queue>
#include<iostream>
using namespace std;

int finfKthSmallest(vector<int>& nums, int k)
{
    
    
	priority_queue<int, vector<int> > Q;//建立最大堆 
	//注意“vector<int>”与后边的“>”中间有一个空格,否侧程序出错。
	
	for(int i=0; i<nums.size(); i++)
	{
    
    
		if(Q.size()<k)
		{
    
    
			Q.push(nums[i]);
		}
		else if(Q.top()>nums[i])
		{
    
    
			Q.pop();
			Q.push(nums[i]);
		}
	}
	
	return Q.top();
}

int main()
{
    
    
	int n, num;
	vector<int> nums;
	cin >> n;
	
	for(int i=0; i<n; i++)
	{
    
    
		scanf("%d", &num);
		nums.push_back(num);
	}
	
	printf("%d", finfKthSmallest(nums, 3));
	
	return 0;
}

Приведенная выше ссылка на код: https://blog.csdn.net/weixin_44208324/article/details/104483788
вставьте сюда описание изображения

Сначала поймай вора, поймай короля и проверь

//并查集
#include<iostream>

int f[1000]={
    
    0}, n, m, k, sum=0;
//f数组初始化 
void init()
{
    
    
	for(int i=1; i<=n; i++)
		f[i]=i;
	return ;
}
//找祖宗 
int getf(int v)
{
    
    
	if(f[v]==v)
	{
    
    
		return v;
	}
	else
	{
    
    
		f[v] = getf(f[v]);
		return f[v];
	}
}
//靠左原则 
void merge(int u, int v)
{
    
    
	int t1 = getf(f[v]);
	int t2 = getf(f[u]);
	
	if(t1 != t2)
	{
    
    
		f[t2] = t1;
	}
	return ;
}

int main()
{
    
    
	scanf("%d %d", &n, &m);
	
	init();
	
	int x, y;
	for(int i=1; i<=m; i++)
	{
    
    
		scanf("%d %d", &x, &y);
		merge(x, y);
	}
	
	for(int i=1; i<=n; i++)
	{
    
    
		if(f[i] == i)
			sum++;//独立树的个数 
	}
	
	printf("%d", sum);
	return 0;
}

вставьте сюда описание изображения

другие алгоритмы

Дерево отрезков, массив деревьев, дерево Trie (словарное дерево), бинарное дерево поиска, красно-черное дерево (сбалансированное бинарное дерево поиска) и т. д.

Supongo que te gusta

Origin blog.csdn.net/m0_46161051/article/details/113663294
Recomendado
Clasificación