Algoritmos e Estruturas de Dados (3)

pilha

1. A estrutura heap é uma estrutura de árvore binária completa implementada com um array.O
subscrito do filho esquerdo do nó raiz é: 2 i+1, e o subscrito do filho direito é 2 i+2. O nó pai dos dois filhos é (i-1)/2 arredondado para 2.
Em uma árvore binária completa, se o valor máximo de cada subárvore estiver no topo, trata-se de uma grande pilha raiz.
Compare o filho com o nó nó pai de baixo para cima. Se a folha filho Se o valor do nó for maior que o nó raiz, então troque, caso contrário, pare a comparação ascendente 3,
na árvore binária completa, se o valor mínimo de cada subárvore estiver em o topo, o heap raiz pequeno é
oposto ao heap raiz grande
4, o heapInsert e o heapify da estrutura do heap operam
na raiz grande A comparação entre o heap e o heap raiz pequeno é o processo de heapInsert; a
demonstração de código do heap heap raiz grande heapInsert:

void heapify(vector<int> &a, int index)
{
    
    
	while (a[index] > a[(index - 1) / 2])
	{
    
    
		//两个元素互换
		swap(a, a[index], a[(index - 1) / 2]);
		//向上反馈
		index = (index - 1) / 2;
	}
}

Operação Heapify:
aqui está um exemplo, quando o usuário deseja excluir o valor máximo no heap raiz grande, primeiro precisamos substituir o último número na matriz para a posição 0 na matriz e, em seguida, o nó raiz começa a comparar com o valor mínimo dos dois nós cotilédones Troque e, em seguida, compare e troque o nó raiz substituído com os dois nós cotilédones na posição atual após a troca.

void heapify(vector<int> &a, int index, int heapsize)
{
    
    
	//index表示从何位置开始进行heapify操作操作
	//heapsize表示数组的长度
	//设置左孩子的下标
	int left = index*2+1;
	//如果当前根节点还有叶节点,则操作
	while(left < heapsize)
	{
    
    
		//两个孩子中,谁的值大,则把下标给largest
		int largest = left + 1 < heapsize && a[left+1] > a[left]? left+1 : left;
		//父和孩子之间的最大值谁最大,将下标给largest
		largest = a[largest] > a[index] ? largest :index;
		
		//如果最大值就是根节点,则退出
		if(largest == index)
			break;
		
		//否则则交换
		swap(a, index, largest);
		index = largest;
		left = index*2+1;
	}
}

Dois, tipo de heap

Idéias:
1. Organize a matriz em uma estrutura de heap e forme um grande heap raiz por meio da operação heapInsert
2. Troque o nó na posição 0 do grande heap raiz pelo último nó, diminua o tamanho do heap em 1 e coloque o último elemento no heap na posição 0, execute a operação de heapify
3. Repita a etapa 2 até que o tamanho do heap seja 0 e a
animação da operação final seja exibida:
Adicione uma descrição da imagem

Código:

void heapify(vector<int>&a, int index1, int heapsize)
{
    
    

	//进行heapifty
	//设置左孩子的节点
	int left = 2 * index1 + 1;

	//如果有左孩子,则开始进行heapifty
	while (left < heapsize)
	{
    
    

		//如果有右孩子,且右孩子的数值较大,则将右孩子的下标设置为largest
		int largest = left + 1 < heapsize && a[left + 1] > a[left] ? left + 1 : left;

		//比较根节点与较大孩子的数值,如果根节点大,则跳出循环
		if (index1 == largest)
		{
    
    
			break;
		}

		//否则互换
		swap(a, index1, largest);

		//设置将最大值的下标赋值给index1,继续向下
		index1 = largest;
		left = 2 * index1 + 1;
	}
}

void heapInsert(vector<int> &a, int index)
{
    
    
	while (a[index] > a[(index - 1) / 2])
	{
    
    
		//两个元素互换
		swap(a, a[index], a[(index - 1) / 2]);

		//向上反馈
		index = (index - 1) / 2;
	}
}

void heapSort(vector<int> &a, int heapsize)
{
    
    

	if (a.size() < 2)
		return;

	//将数组构建成大根堆
	for (int i = heapsize-1; i >= 0; i--)
	{
    
    
		heapify(a, i, heapsize);
	}

	swap(a, 0, --heapsize);
	while (heapsize>0)
	{
    
    
		//将变成大根堆的根节点与数组的最后一个数互换,并且将heapsize减小1
		heapify(a, 0, heapsize);
		swap(a, 0, --heapsize);
	}	
}

3. Extensão de classificação de heap

Uma matriz quase ordenada é conhecida. Quase ordenada significa que, se a matriz for organizada em ordem, cada elemento não pode se mover mais do que k, e k é relativamente pequeno em comparação com a matriz. Escolha um algoritmo de classificação apropriado para classificar esses dados.
Primeiro construímos um pequeno heap raiz com k elementos, porque a distância máxima de movimento é k, portanto, em casos extremos, use este método para colocar o nó raiz do pequeno heap raiz, ou seja, o valor mínimo em 0 e, em seguida, apontar para Em seguida, mova uma posição e, em seguida, coloque o elemento k na matriz abaixo no pequeno heap raiz para formar um pequeno heap raiz novamente e assim por diante. Por fim, exiba os números na pequena pilha de raiz de pequeno para grande.
Em C++, a camada inferior da operação multiconjunto é a estrutura da árvore binária.

void SortArrayDistanceLessK(vector<int> &a, int k)
{
    
    
	//定义一个multiset容器
	multiset<int> s;

	//设置遍历的起始点
	int index = 0;

	//防止k超过数组长度,要限制传入multiset容器的元素数量
	int c = a.size();
	int b = min(c, k);
	for (; index <= b; index++)
	{
    
    
		//将数组的前K个数依次传到multiset容器中
		s.insert(a[index]);
	}

	int i = 0;
	//依次将K后面的元素传入multiset容器中,并弹出第一个元素
	for (; index < a.size(); index++)
	{
    
    
		//将k之后的元素一个一个压入到multiset中
		s.insert(a[index]);

		//将set的第一个元素放到数组的第一个位置,并将multiset容器第一个元素删除
		set<int>::const_iterator it = s.begin();
		a[i] = *it;

		//删除第一个元素
		s.erase(s.begin());
		i++;
	}

	//将multiset容器中的数据以此弹出
	while (!s.empty())
	{
    
    
		//将set的第一个元素放到数组的第一个位置,并将multiset容器第一个元素删除
		set<int>::const_iterator it = s.begin();
		a[i++] = *it;

		//删除第一个元素
		s.erase(s.begin());
	}
}

4. Classificação de balde

Radix sort:
exemplo de código c++

#include <cmath>

int getDigit(int x, int d)
{
    
    
	//返回所需位数的数值
	return((x / (int)pow(10, d - 1)) % 10);
}

//桶排序
void radixSort(vector<int> &a, int L, int R, int digit)
//L:要排序的左区域
//R:要排序的右区域
//digit十进制的位数
{
    
    
	 //以十为基底
	int radix = 10;
	int i = 0, j = 0;

	//设置辅助空间,其大小与数组大小一致
	int *bucket = new int[R - L + 1];

	//有多少位就进出桶多少次,开始入桶
	for (int d = 1; d <= digit; d++)
	{
    
    
		//count[0]为当前位(d位)是0的数字有多少个
		//count[1]为当前位(d位)是0-1的数字有多少个
		//count[2]为当前位(d位)是0-2的数字有多少个
		//count[i]为当前位(d位)是0-i的数字有多少个
		//申请一个辅助数组,记录上面的数据
		int *count = new int[radix];

		//将申请的内存全部附初值0
		for (int i = 0; i < radix; i++)
		{
    
    
			count[i] = 0;		
		}

		//开始入桶操作
		for (i = L; i <=R; i++)
		{
    
    
			j = getDigit(a[i], d);
			count[j]++;
		}

		//对辅助数组处理成前缀和
		for (i = 1; i < radix; i++)
		{
    
    
			count[i] = count[i] + count[i - 1];
		}

		//开始出桶操作
		for (i = R; i >= L; i--)
		{
    
    
			j = getDigit(a[i], d);
			bucket[count[j] - 1] = a[i];	
			count[j]--;
		}

		int j = 0;
		for (i = L; i <= R; i++)
		{
    
    
			a[i] = bucket[j];
			j++;
		}
	}
}

int maxbits(vector<int> &a)
{
    
    
	//定义一个最大数值暂存变量
	int largest = 0;
	for (int i = 0; i < a.size(); i++)
	{
    
    
		largest = max(largest, a[i]);
	}

	//开始计算最大数值的十进制数一共有多少位
	int res = 0;
	while (largest != 0)
	{
    
    
		res++;
		largest /= 10;
	}
	return res;
}


void radixSort(vector<int> &a)
{
    
    
	if (a.size() < 2)
		return;
	radixSort(a, 0, a.size() - 1, maxbits(a));

}

5. A estabilidade e o resumo do algoritmo de classificação

Entre indivíduos de mesmo valor, se a ordem relativa não mudar devido à ordenação, a ordenação é estável; caso contrário, não é.
Ordenação sem estabilidade:
ordenação por seleção, ordenação rápida, ordenação por heap
ordenação com estabilidade:
ordenação por bolhas, ordenação por inserção, ordenação por mesclagem, ordenação sob a ideia de cada balde ordenação
não foi encontrada até agora Complexidade de tempo O(N*logN ), complexidade de espaço extra 0(1) e ordenação estável.
insira a descrição da imagem aquiPerceber!
1. A complexidade de espaço adicional do merge sort pode ser O(1), mas é muito difícil e não precisa ser dominada. Se você estiver interessado, pode procurar por "método de cache interno do merge sort".

2. "Ordenação de mesclagem no local" fará com que a complexidade de tempo da ordenação de mesclagem se torne o(N^2
) 3. A ordenação rápida pode resolver problemas de estabilidade, mas é muito difícil e você não precisa dominá-la. procure por "01stable sort"
4 , todas as melhorias não são importantes, porque não há complexidade de tempo 0(N*logN), complexidade de espaço extra 0(1) e classificação estável.
5. Existe uma questão que coloca números ímpares no lado esquerdo da matriz e números pares no lado direito da matriz e exige que a ordem relativa original permaneça inalterada.É muito difícil encontrar esse problema.

Acho que você gosta

Origin blog.csdn.net/qq_52302919/article/details/131037538
Recomendado
Clasificación