Dando continuidade ao estudo da estrutura de dados lista encadeada, vamos aprender nesta aula como inserir de forma ordenada na estrutura de dados lista encadeada. Nesta aula usaremos apenas a estrutura Nó. Na aula seguinte usaremos a estrutura Lista.
O processo para inserir de forma ordenada é composto de várias etapas mas nada muito diferente do que já estudamos até aqui. Após a criação do novo nó, o primeiro passo é verificar se a lista está vazia, neste caso teremos uma inserção no início.
/*
a lista está vazia?
*/
if(*lista == NULL){
novo->proximo = NULL;
*lista = novo;
}
else{
// ...
}
Se a lista não estiver vazia, é possível que o novo elemento a ser inserido seja o menor, então precisamos verificar também esta possibilidade, comparando o elemento a ser inserido com o primeiro elemento da lista.
/*
a lista está vazia?
*/
if(*lista == NULL){
novo->proximo = NULL;
*lista = novo;
}
else if(novo->valor < (*lista)->valor){ // é menor que o primeiro elemento da lista?
novo->proximo = *lista;
*lista = novo;
}
else{
// ...
}
Por fim, se o novo elemento não é menor que o primeiro elemento da lista, então teremos uma inserção no meio ou no final, neste caso precisamos percorrer a lista procurando pela posição correta para inserir o elemento.
/*
a lista está vazia?
*/
if(*lista == NULL){
novo->proximo = NULL;
*lista = novo;
}
else if(novo->valor < (*lista)->valor){ // é menor que o primeiro elemento da lista?
novo->proximo = *lista;
*lista = novo;
}
else{
aux = *lista;
while(aux->proximo && novo->valor > aux->proximo->valor)
aux = aux->proximo;
novo->proximo = aux->proximo;
aux->proximo = novo;
}
A seguir temos o procedimento completo para realizar a inserção de forma ordenada em nossa lista simplesmente encadeada.
/*
Procedimento para inserir ordenado
*/
void inserir_ordenado(No **lista, int num){
No *aux, *novo = malloc(sizeof(No));
if(novo){
novo->valor = num;
if(*lista == NULL){ // a lista está vazia?
novo->proximo = NULL;
*lista = novo;
}
else if(novo->valor < (*lista)->valor){ // é o menor?
novo->proximo = *lista;
*lista = novo;
}
else{ // inserção no meio ou no final da lista
aux = *lista;
while(aux->proximo && novo->valor > aux->proximo->valor)
aux = aux->proximo;
novo->proximo = aux->proximo;
aux->proximo = novo;
}
}
else
printf("Erro ao alocar memoria!\n");
}
Código de exemplo completo em C para a estrutura Lista Encadeada
/*
Código escrito por Wagner Gaspar
Agosto de 2021
Aula 248: Lista Simplesmente Encadeada
Como inserir de forma ordenada SEM a estrutura lista?
*/
typedef struct no{
int valor;
struct no *proximo;
}No;
// procedimento para inserir no início
void inserir_no_inicio(No **lista, int num){
No *novo = malloc(sizeof(No));
if(novo){
novo->valor = num;
novo->proximo = *lista;
*lista = novo;
}
else
printf("Erro ao alocar memoria!\n");
}
// procedimento para inserir no fim
void inserir_no_fim(No **lista, int num){
No *aux, *novo = malloc(sizeof(No));
if(novo){
novo->valor = num;
novo->proximo = NULL;
// é o primeiro?
if(*lista == NULL)
*lista = novo;
else{
aux = *lista;
while(aux->proximo)
aux = aux->proximo;
aux->proximo = novo;
}
}
else
printf("Erro ao alocar memoria!\n");
}
// procedimento para inserir no meio
void inserir_no_meio(No **lista, int num, int ant){
No *aux, *novo = malloc(sizeof(No));
if(novo){
novo->valor = num;
// é o primeiro?
if(*lista == NULL){
novo->proximo = NULL;
*lista = novo;
}
else{
aux = *lista;
while(aux->valor != ant && aux->proximo)
aux = aux->proximo;
novo->proximo = aux->proximo;
aux->proximo = novo;
}
}
else
printf("Erro ao alocar memoria!\n");
}
void inserir_ordenado(No **lista, int num){
No *aux, *novo = malloc(sizeof(No));
if(novo){
novo->valor = num;
// a lista está vazia?
if(*lista == NULL){
novo->proximo = NULL;
*lista = novo;
} // é o menor?
else if(novo->valor < (*lista)->valor){
novo->proximo = *lista;
*lista = novo;
}
else{
aux = *lista;
while(aux->proximo && novo->valor > aux->proximo->valor)
aux = aux->proximo;
novo->proximo = aux->proximo;
aux->proximo = novo;
}
}
else
printf("Erro ao alocar memoria!\n");
}
void imprimir(No *no){
printf("\n\tLista: ");
while(no){
printf("%d ", no->valor);
no = no->proximo;
}
printf("\n\n");
}
int main(){
int opcao, valor, anterior;
No *lista = NULL;
do{
printf("\n\t0 - Sair\n\t1 - InserirI\n\t2 - inserirF\n\t3 - InserirM\n\t4 - InserirO\n\t5 - Imprimir\n");
scanf("%d", &opcao);
switch(opcao){
case 1:
printf("Digite um valor: ");
scanf("%d", &valor);
inserir_no_inicio(&lista, valor);
break;
case 2:
printf("Digite um valor: ");
scanf("%d", &valor);
inserir_no_fim(&lista, valor);
break;
case 3:
printf("Digite um valor e o valor de referencia: ");
scanf("%d%d", &valor, &anterior);
inserir_no_meio(&lista, valor, anterior);
break;
case 4:
printf("Digite um valor: ");
scanf("%d", &valor);
inserir_ordenado(&lista, valor);
break;
case 5:
imprimir(lista);
break;
default:
if(opcao != 0)
printf("Opcao invalida!\n");
}
}while(opcao != 0);
return 0;
}
