ponteiro para o primeiro no, que e a cabeca dalista. Cada no contem um ponteiro que aponta para a struct que e a sua sucessora na lista. Oponteiro da ultima struct da lista aponta para NULL, indicando que se chegou ao final da lista.Esta estrutura de dados e criada dinamicamente na memoria (utiliza-se malloc() e free()), demodo que se torna simples introduzir nos nela, retirar nos, ordenar os nos, etc. Nao vamosentrar em detalhes sobre todos os algoritmos que poderiamos criar em uma lista encadeada,pois isto geralmente e feito em cursos de algoritmos e estruturas de dados, nao se incluindo noescopo deste curso. Aqui, veremos somente formas de se criar uma lista encadeada em C etambem maneiras simples de percorrer esta lista.Supondo que queiramos criar uma lista encadeada para armazenar os produtosdisponiveis em uma loja. Poderiamos criar um no desta lista usando a seguinte struct:struct Produto {int codigo; /* Codigo do produto */double preco; /* Preco do produto */struct Produto *proximo; /* Proximo elemento da listaencadeada de Produtos */};Note que esta struct possui, alem dos campos de dados codigo e preco, um campoadicional que e um ponteiro para uma struct do tipo Produto. E este campo que sera utilizadopara apontar para o proximo no da lista encadeada. O programa a seguir faz uso desta struct,atraves de um novo tipo criado por um typedef, para criar uma lista de produtos de uma loja:#include <stdio.h>#include <stdlib.h>/* Estrutura que sera usada para criar os nos da lista */typedef struct tipo_produto {int codigo; /* Codigo do produto */double preco; /* Preco do produto */109struct tipo_produto *proximo; /* Proximo elemento da lista encadeada de Produtos */} TProduto;/* Prototipos das funcoes para inserir e listar produtos */void inserir(TProduto **cabeca);void listar (TProduto *cabeca);int main(){TProduto *cabeca = NULL; /* Ponteiro para a cabeca da lista */TProduto *noatual; /* Ponteiro a ser usado para percorrer a lista no momento dedesalocar seus elementos*/char q; /* Caractere para receber a opcao do usuario */do {printf("\n\nOpcoes: \nI -> para inserir novo produto;\nL -> para listar os produtos; \nS -> para sair \n:");scanf("%c", &q); /* Le a opcao do usuario */switch(q) {case i: case I: inserir(&cabeca); break;case l: case L: listar(cabeca); break;case s: case S: break;default: printf("\n\n Opcao nao valida");}fflush(stdin); /* Limpa o buffer de entrada */} while ((q != s) && (q != S) );/* Desaloca a memoria alocada para os elementos da lista */noatual = cabeca;while (noatual != NULL){cabeca = noatual->proximo;free(noatual);noatual = cabeca;}}/* Lista todos os elementos presentes na lista encadeada */void listar (TProduto *noatual){int i=0;while( noatual != NULL) /* Enquanto nao chega no fim da lista */{i++;printf("\n\nProduto numero %d\nCodigo: %d \nPreco:R$%.2lf", i, noatual->codigo,noatual->preco);noatual = noatual->proximo; /* Faz noatual apontar para o proximo no */}}/* Funcao para inserir um novo no, ao final da lista */110void inserir (TProduto **cabeca){TProduto *noatual, *novono;int cod;double preco;printf("\n Codigo do novo produto: ");scanf("%d", &cod);printf("\n Preco do produto:R$");scanf("%lf", &preco);if (*cabeca == NULL) /* Se ainda nao existe nenhum produto na lista */{/* cria o no cabeca */*cabeca = (TProduto *) malloc(sizeof(TProduto));(*cabeca)->codigo = cod;(*cabeca)->preco = preco;(*cabeca)->proximo = NULL;}else{/* Se ja existem elementos na lista, deve percorre-la ate o seu final