Sorting Simple Linked List - C - c

[UPTATED WITH ANSWER AT THE END] I tried many things but I still don't know how I can do any sorting with a simple linked list. It should be sorted like the number saved on each node goes from the lower till the higher one. What can I do?
I'm not allowed to sort the numbers as I save then on the list. The sorting must be made after the list is complete.
the code isn't completely ready yet
#include <stdlib.h>
#include <stdio.h>
#include <math.h>
#include <string.h>
#define pi 3.14159265359
#define N 50
typedef struct lista{
char palavra[N];
int repeticao;
struct lista *prox;
} Lista;
Lista* lista_cria(){
return NULL;
}
int vazia(Lista *LISTA){
if(LISTA->prox == NULL) return 1;
else return 0;
}
void insere(Lista **lis, char *s){
Lista* novo = (Lista*) malloc (sizeof(Lista));
strcpy(novo->palavra, s);
novo->prox = NULL;
while (*lis)
lis = &(*lis)->prox;
*lis = novo;
}
Lista* retira(Lista* lis, char *s){
Lista* ant = NULL;
Lista* p = lis;
while(p != NULL && (strcmp(s, p->palavra) != 0)){
ant = p;
p = p->prox;
}
if(p == NULL) return lis;
if(ant == NULL) lis = p->prox;
else ant->prox = p->prox;
free(p);
return lis;
}
void imprimir_lista(Lista* lis){
Lista* p;
for(p = lis; p != NULL; p = p->prox)
printf("%s ", p->palavra);
printf("\n \n");
}
int busca(Lista* lis, char *s){
Lista *p;
int cont = 0;
for(p = lis; p != NULL; p = p->prox){
if(strcmp(p->palavra, s) == 0) cont++;
}
return cont;
}
Lista* repeticao(Lista* lis, int i){
Lista *p;
char s[50];
int cont;
printf("\n \n Doc%d", i);
for(p = lis; p != NULL; p = p->prox){
strcpy(s, p->palavra);
cont = busca(p, s);
printf(" \n\t %s: %d ", s, cont);
p->repeticao = cont;
}
return lis; /* return p*/
}
void liberar_lista(Lista *lis){
Lista *aux = lis;
while (aux != NULL) {
Lista *aux2 = aux->prox;
free(aux);
aux = aux2;
}
}
float produto_escalar (Lista *lis1, Lista *lis2) {
Lista *aux1 = lis1, *aux2 = lis2;
float resultado=0;
while (aux1 != NULL) {
while (aux2 != NULL) {
if (strcmp(aux1->palavra, aux2->palavra) == 0 ) {
resultado+=(aux1->repeticao*aux2->repeticao);
aux2 = aux2->prox;
break;
}
else {
aux2 = aux2->prox;
}
}
aux1 = aux1->prox;
aux2 = lis2;
}
return resultado;
}
float formula (Lista *lis1, Lista *lis2){
float resultado;
resultado = acos(produto_escalar(lis1, lis2)/(sqrt(produto_escalar(lis1, lis1))*sqrt(produto_escalar(lis2, lis2))));
resultado = (((resultado *50)*4)/pi)-100;
if (resultado<0){
resultado*=-1;
}
return resultado;
}
void checa_plagio (float resultado) {
if (resultado>=50) {
printf("\n O arquivo foi plagiado. \n\t Arquivo é %.3f%% parecido.", resultado);
}
else
printf("\n O arquivo não foi plagiado \n\t Arquivo é %.3f%% parecido.", resultado);
}
int main () {
char arquivo1[] = "doc1.txt", arquivo2[] = "doc2.txt";
char string[50];
double resposta;
FILE *fp1, *fp2;
Lista *lista1, *lista2;
lista1 = lista_cria();
lista2 = lista_cria();
fp1 = fopen (arquivo1, "r+") ;
if (fp1 == NULL) {
printf("\nErro. Não foi possível abrir o arquivo.\n");
return EXIT_FAILURE;
}
while(!feof(fp1)){
fscanf(fp1, "%s[A-Z a-z]", string);
insere(&lista1, string);
}
fclose(fp1);
fp2 = fopen (arquivo2, "r+") ;
if (fp2 == NULL) {
printf("\nErro. Não foi possível abrir o arquivo.\n");
return EXIT_FAILURE;
}
while(!feof(fp2)){
fscanf(fp2, "%s[A-Z a-z]", string);
insere(&lista2, string);
}
fclose(fp2);
/*imprimir_lista(lista1);
imprimir_lista(lista2);*/
lista1 = repeticao(lista1, 1);
lista2 = repeticao(lista2, 2);
resposta = formula (lista1, lista2);
checa_plagio(resposta);
liberar_lista(lista1);
liberar_lista(lista2);
return EXIT_SUCCESS;
}
[UPDATED WITH ANSWER]
THE CODE I USED TO SORT:
#define N 50
#include <stdlib.h>
#include <stdio.h>
typedef struct lista{
char palavra[N];
int repeticao;
struct lista *prox;
} Lista;
Lista* sort (Lista *lis) {
Lista *temp, *empurra;
Lista *aux1, *aux2;
Lista *guarda;
aux1 = NULL;
for (temp = lis; temp != NULL; temp = temp->prox){
aux2 = temp;
for (empurra=temp->prox; empurra != NULL; empurra = empurra->prox){
if (empurra->repeticao < temp->repeticao){
guarda = temp->prox;
temp->prox = empurra->prox;
if(guarda == empurra)
empurra->prox = temp;
else
empurra->prox = guarda;
if(aux2 != temp)
aux2->prox = temp;
if(aux1)
aux1->prox = empurra;
else
lis = empurra;
guarda = temp;
temp = empurra;
empurra = guarda;
}
aux2 = empurra;
}
aux1 = temp;
}
return lis;
}
int main (){
return 0;
}

I think the most learning approach that you can take, it's to think that the linked list is an array. With that approach you can simply, access the elements of the array and apply a sort algorithm (like bubble sort) and when make the swap of the elements using the pointer to the elements. With that would be just a matter to redirect the pointers (to next elements) for the right elements.
Also, pay attention to the particular cases of the sorts (the beginning and the end of list, in this case).
Here's a example:
Suppose that we have the structure for the linked list:
typedef struct list{
int n;
struct list *next;
} List;
And we want to sort the linked list using the int n, a code example would be something like this:
void sort (List * begin) {
List *currentElement, *previousElement;
int swapped = 1;
while (swapped) {
swapped = 1;
while (swapped != 0) {
swapped = 0;
currentElement = begin;
previousElement = NULL; //No previous element in the beginning of the list
while(currentElement->next != NULL) { //Has another element, it's not the end of the list
List *nextElement = currentElement->next;
if(currentElement->n > nextElement->n) {
//swapping the elements
if (previousElement == NULL) { //is the first element
List *auxPtr = nextElement->next;
nextElement->next = currentElement;
currentElement->next = auxPtr;
begin = nextElement; //nextElement is the first element of the list now
}
else {
previousElement->next = nextElement;
currentElement->nextElement->next;
nextElement->next = currentElement;
}
previousElement = nextElement; //The nextElement is 'behind' the currentElement so it should be the previousElement
swapped = 1; // a swap was made
//The elements where swapped so currentElement is already in the 'position' of the next element, there is no need to upload it value
}
else { // there is no need to swap, just walk foward in the list
previousElement = currentElement;
currentElement = nextElement;
}
}
}
}
}
I used a simple bubble sort for the sorting

Related

Verify if a binary tree is a mirror of another binary tree

I am making a program in C language that aims to identify if two binary trees are mirror. In my program I have managed to create two trees with the structure that can be seen in the following image:
My problem is that I don't know how to create a recursive method to verify that the two binary trees are mirrored, one with respect to the other; I have tried to create the method, but I only manage to compare the root of the two binary trees, I can't get beyond the beginning.
Attached is the code I have so far.
#include <stdlib.h>
#include <stdio.h>
#include <stdbool.h>
//Define the structure for the two binary trees
typedef struct{
int dato;
struct nodo *izq;
struct nodo *der;
}nodo;
typedef struct{
int dato;
struct nodo *izq;
struct nodo *der;
}nodo1;
//Define auxiliary pointers
nodo *raiz = NULL;/
nodo1 *raiz1 = NULL;//
//Function to add nodes
void insertarNodo(int datoI){
nodo *nuevo = malloc(sizeof(nodo));
nuevo->dato = datoI;
nuevo->izq = NULL;
nuevo->der = NULL;
if(raiz == NULL)
raiz = nuevo;
else{
nodo *anterior, *recorrer;
anterior = NULL;
recorrer = raiz;
while(recorrer != NULL){
anterior = recorrer;
if(datoI < recorrer->dato)
recorrer = recorrer->izq;
else
recorrer = recorrer->der;
}
if(datoI < anterior->dato)
anterior->izq = nuevo;
else
anterior->der = nuevo;
}
}
//Function to add nodes
void insertarNodo1(datoI){
nodo1 *nuevo = malloc(sizeof(nodo1));
nuevo->dato = datoI;
nuevo->izq = NULL;
nuevo->der = NULL;
if(raiz1 == NULL)
raiz1 = nuevo;
else{
nodo1 *anterior, *recorrer;
anterior = NULL;
recorrer = raiz1;
while(recorrer != NULL){
anterior = recorrer;
if(datoI > recorrer->dato)
recorrer = recorrer->izq;
else
recorrer = recorrer->der;
}
if(datoI > anterior->dato)
anterior->izq = nuevo;
else
anterior->der = nuevo;
}
}
void mostrarArbol1(nodo *arbol, int contador){
int i = 0;
if(arbol == NULL){
return;
}else{
mostrarArbol1(arbol->der,contador+1);
for(i=0; i<contador;i++)
printf(" ");
printf("(%d)\n",arbol->dato);
mostrarArbol1(arbol->izq,contador+1);
}
}
void mostrarArbol2(nodo1 *arbol, int contador){
int i = 0;
if(arbol == NULL){
return;
}else{
mostrarArbol2(arbol->der,contador+1);
for(i=0; i<contador;i++)
printf(" ");
printf("(%d)\n",arbol->dato);
mostrarArbol2(arbol->izq,contador+1);
}
}
//Recursive method I need help with
void isMirror(nodo* p,nodo1* q) {
if(p->dato == q->dato){
printf("Mirrors");
}
else{
printf("Not mirrors");
}
isMirror(p->der, q->izq);
}
int main(){
insertarNodo(20);
insertarNodo(8);
insertarNodo(22);
insertarNodo(25);
insertarNodo(12);
insertarNodo(14);
insertarNodo(10);
insertarNodo(14);
insertarNodo1(20);
insertarNodo1(8);
insertarNodo1(22);
insertarNodo1(25);
insertarNodo1(12);
insertarNodo1(4);
insertarNodo1(10);
insertarNodo1(14);
mostrarArbol1(raiz, 0);
printf("\n\n--------------------------\n\n");
mostrarArbol2(raiz1, 0);
printf("\n\n--------------------------\n\n");
isMirror(raiz, raiz1);
return 0;
}
Could you please help me?
Thank you very much in advance.
Try the below fix for your isMirror function. We just take left from first root node and right from second root node and compare their values.
void isMirror(nodo* p,nodo1* q) {
if(!p || !q) return;
if(p->dato == q->dato){
printf("%d Mirrors\n", p->dato);
} else {
printf("%d %d Not mirrors\n", p->dato,q->dato);
}
isMirror(p->der, q->izq);
isMirror(q->der, p->izq);
}
Update: added boolean result return
bool isMirror(nodo* p,nodo1* q) {
if(!p && !q) return true;
if(!p || !q) return false;
bool result = true;
if(p->dato == q->dato){
printf("%d Mirrors\n", p->dato);
} else {
printf("%d %d Not mirrors\n", p->dato,q->dato);
return false;
}
result = result && isMirror(p->der, q->izq);
result = result && isMirror(q->der, p->izq);
return result;
}
Recursive way
int isMirror(nodo* p,nodo1* q) {
if (p == NULL && q == NULL)) return 1; // Reached the end of the line
if (p != NULL || q != NULL) return 0; // One branch is longer than the other
if(p->dato != q->dato){
return 0; // Not the same
}
return isMirror(p->der, q->izq) && isMirror(q->der, p->izq); // Both the same?
}
For starters the function should be declared like
bool isMirror( const nodo *p, const nodo1 *q );
That is its parameters should have the qualifier const because passed nodes are not changed within the function. And the function should do one thing: to check whether one binary tree is a mirror of another binary tree, It is the caller of the function that decides whether to output a message.
The function can be defined the following way
bool isMirror( const nodo *p, const nodo1 *q )
{
return ( p == NULL && q == NULL ) ||
( p != NULL && q != NULL &&
p->dato == q->dato &&
isMirror( p->izq, q->der ) &&
isMirror( p->der, q->izq ) );
}
Then in main you can write
printf( "raiz1 is a mirror of raiz is %s\n",
isMirror( raiz, raiz1 ) ? "true" : "false" );

Enter Data in linked-list

I need to insert every character of a message into a linked list, but I don't understand where I am going wrong
I'm allocating right, but at the time of printing the message, is giving error
Can someone help me?
As Struct
struct mensagem{
char msg;
char chave;
};
struct elemento{
struct mensagem dados;
struct elemento *prox;
};
typedef struct elemento* Lista;
typedef struct elemento Elem;
The functions- Build list , insert element and print list
Lista* cria_lista(){
Lista* li = (Lista*) malloc(sizeof(Lista));
if(li != NULL)
*li = NULL;
return li;
}
int insere_lista_final(Lista* li, struct mensagem al){
if(li == NULL)
return 0;
Elem *no;
no = (Elem*) malloc(sizeof(Elem));
if(no == NULL)
return 0;
no->dados = al;
no->prox = NULL;
if((*li) == NULL){//lista vazia: insere início
*li = no;
}else{
Elem *aux;
aux = *li;
while(aux->prox != NULL){
aux = aux->prox;
}
aux->prox = no;
}
return 1;
}
void imprime_lista(Lista* li){
if(li == NULL)
return 0;
Elem* no = *li;
while(no != NULL){
printf("%c1",no->dados.msg);
no = no->prox;
}
}
Int main
int main()
{
int mod_exec=1,i=0;
char c;
struct mensagem al;
Lista* li = cria_lista();
while((c = getchar()) != '\n')
{
insere_lista_final(li,al);
imprime_lista(li);
}
return 0 ;
}
typedef struct elemento* Lista;
typedef struct elemento Elem;
Lista* cria_lista(){
Lista* li = (Lista*) malloc(sizeof(Lista));
if(li != NULL)
*li = NULL;
return li;
}
int insere_lista_final(Lista* li, struct mensagem al){
if(li == NULL)
return 0;
Elem *no;
no = (Elem*) malloc(sizeof(Elem));
if(no == NULL)
return 0;
no->dados = al;
no->prox = NULL;
if((*li) == NULL){//lista vazia: insere início
*li = no;
}else{
Elem *aux;
aux = *li;
while(aux->prox != NULL){
aux = aux->prox;
}
aux->prox = no;
}
return 1;
}
void imprime_lista(Lista* li){
if(li == NULL)
return 0;
Elem* no = *li;
while(no != NULL){
printf("%c1",no->dados.msg);
no = no->prox;
}
}
Int main
int main()
{
int mod_exec=1,i=0;
char c;
struct mensagem al;
Lista* li = cria_lista();
while((c = getchar()) != '\n')
{
insere_lista_final(li,al);
imprime_lista(li);
}
return 0 ;
}
Adding a main function with properly initialized variables didn't lead me to errors:
int main(void)
{
Lista *l = cria_lista();
struct mensagem m1 = { .msg = 'a', .chave = 'b'};
struct mensagem m2 = { .msg = 'c', .chave = 'd'};
insere_lista_final(l,m1);
insere_lista_final(l,m2);
imprime_lista(l);
return 0;
}
Be sure your trigger warnings flags when compiling.

Trying to delete all the elements from HashTable with the status marked as closed

#include<iostream>
using namespace std;
enum Stare {DESCHIS=10, LUCRU=20, DUPLICAT=30, REZOLVAT=40, INCHIS=50};
struct Task
{
char *idTask;
char *data;
char *numeInginer;
int nivelComplexitate;
Stare stare;
};
struct List
{
Task *task;
List*next;
};
struct HashTable
{
List** vector;
int size;
};
List* creareNodLista(Task *task)
{
List*nod = (List*)malloc(sizeof(List));
nod->task = task;
nod->next = NULL;
return nod;
}
void initHashTable(HashTable &hTable, int size)
{
hTable.vector = (List**)malloc(sizeof(List*)*size);
hTable.size = size;
memset(hTable.vector, 0, sizeof(List*)*size);
}
int fhash(char c, int l)
{
return c%l;
}
void inserareNodLista(List*&list, List*nod)
{
nod->next = list;
list = nod;
}
void inserareNodHashTable(HashTable hTable, List*nod)
{ //determinarea pozitiei pe care se face inserarea
int index = fhash(nod->task->numeInginer[0],hTable.size);
//obtinerea listei in care se face inserarea
List*list = hTable.vector[index];
//inserare element nou in lista
inserareNodLista(list, nod);
//actualizare element in hashTable
hTable.vector[index] = list;
}
List* getHashTable(HashTable ht, char cheie)
{
int f = fhash(cheie, ht.size);
return ht.vector[f];
}
void printHashTable(HashTable ht)
{
for (char c = 'A'; c < 'Z'; c++)
{
List*lista = getHashTable(ht, c);
int count = 0;
while (lista)
{
count++;
printf("%d", count);
printf("%s\n", lista->task->idTask);
printf("%s\n", lista->task->data);
printf("%s\n", lista->task->numeInginer);
printf("%d\n", lista->task->nivelComplexitate);
printf("%d\n", lista->task->stare);
lista = lista->next;
}
if (count>1)
printf("\nColiziune\n\n");
}
}
int stergeNodHashTable(HashTable hTable, char*numeInginer)
{
int pozitie = 0;
pozitie = fhash(numeInginer[0], hTable.size);
if (hTable.vector[pozitie] == NULL)
return -1;
else
{
if (strcmp(hTable.vector[pozitie]->task->numeInginer, numeInginer) == 0)
{
if (hTable.vector[pozitie]->next == NULL)
{
free(hTable.vector[pozitie]->task->idTask);
free(hTable.vector[pozitie]->task->data);
free(hTable.vector[pozitie]->task->numeInginer);
free(hTable.vector[pozitie]->task);
free(hTable.vector[pozitie]);
hTable.vector[pozitie] = NULL;
}
else
{
List*lista = hTable.vector[pozitie];
hTable.vector[pozitie] = lista->next;
free(lista->task->idTask);
free(lista->task->data);
free(lista->task->numeInginer);
free(lista->task);
free(lista);
lista->next = NULL;
lista = NULL;
}
}
else
{
List*tmp = hTable.vector[pozitie];
while (tmp->next != NULL && strcmp(tmp->next->task->numeInginer, numeInginer) != 0)
tmp = tmp->next;
List*list = tmp->next;
if (list->next == NULL)
{
free(list->task->idTask);
free(list->task->numeInginer);
free(list->task->data);
free(list->task);
free(list);
tmp->next = NULL;
list = NULL;
}
else
{
List*tmp = list;
list = list->next;
free(tmp->task->idTask);
free(tmp->task->data);
free(tmp->task->numeInginer);
free(tmp->task);
free(tmp);
tmp->next = NULL;
tmp = NULL;
}
}
}
return pozitie;
}
void main()
{
FILE *pFile = fopen("Text.txt", "r");
Task *task = NULL;
HashTable ht;
initHashTable(ht, 29);
if (pFile)
{
while (!feof(pFile))
{
task = (Task*)malloc(sizeof(Task));
char id[50];
fscanf(pFile, "%s", &id);
task->idTask = (char*)malloc(strlen(id) + 1);
strcpy(task->idTask, id);
char data[50];
fscanf(pFile, "%s", data);
task->data = (char*)malloc(strlen(data) + 1);
strcpy(task->data, data);
char numeInfiner[50];
fscanf(pFile, "%s", numeInfiner);
task->numeInginer = (char*)malloc(strlen(numeInfiner) + 1);
strcpy(task->numeInginer, numeInfiner);
fscanf(pFile, "%d", &task->nivelComplexitate);
fscanf(pFile, "%d", &task->stare);
//creare element lista
List*nod = creareNodLista(task);
//inserare element in hashTable
inserareNodHashTable(ht, nod);
}
fclose(pFile);
for (char c = 'A'; c < 'Z'; c++)
{
List *lista = getHashTable(ht, c);
while (lista)
{
if (lista->task->stare == 50)
stergeNodHashTable(ht, lista->task->numeInginer);
}
}
printHashTable(ht);
}
}
I am trying to delete from hashTable all the elements with status marked as closed. The delete function is working fine but when i call it for al the hashtable, it got me error: lista->task was 0xDDDDDD. I cant understand why. Please help me!

printing a pointer value

i have this issue while trying to print *p value while p is pointed to a nodo of the list (obviusly i would like to print the nodo.info value)
here is the code, hope u understand:
struct nodo {
int info;
struct nodo *prec;
struct nodo *succ;
} ;
typedef struct nodo nodo;
int main (void) { // just declaring my 3 nodos
struct nodo *p;
struct nodo anodo;
struct nodo bnodo;
struct nodo cnodo;
anodo.info = 200;
anodo.prec = NULL;
anodo.succ = NULL;
bnodo.info = 22;
bnodo.prec = NULL;
bnodo.succ = NULL;
cnodo.info = 2000;
cnodo.prec = NULL;
cnodo.succ = NULL;
anodo.succ = &bnodo;
bnodo.prec = &anodo;
bnodo.succ = &cnodo;
cnodo.prec = &bnodo;
p = &anodo;
printf("\n%d\n", checklist (p)); // calling function
return 0;
}
nodo *checklist (struct nodo *p) {
int j=0;
while (p != NULL) {
if (p->info >= p->succ->info) { //if first element is major or same than next
p=p->succ;
} else {
while (p != NULL) {
if (p->info >= p->succ->info) { //same
p=p->succ;
j++;
} else {
p = NULL;
}
}
}
}
while (j != 0) {
p = p->prec; //used a counter to get back to the first nodo in wich next was less than prev
j--;
}
return p;
}
feel free to ask any details
p = checklist (p);
if (p)
printf("\n%d\n", p->info);
You need to return the nodo.info then
int checklist (struct nodo *p) {
int j=0;
while (p != NULL) {
/* avoid this p->succ->info */
if (p->info >= p->succ->info) { //if first element is major or same than next
p = p->succ;
} else {
while (p != NULL) {
if (p->info >= p->succ->info) { //same
p = p->succ;
j++;
} else {
p = NULL;
}
}
}
}
while (j != 0) { p = p->prec; //used a counter to get back to the first nodo in wich next was less than prev
j--;
}
return p->info;
}
or in main
int info
struct nodo *found;
found = checklist(p);
if (found != NULL)
printf("\n%d\n", found->info);

Implementing ADT Priority Que as linked list, can't sort elements

I am implementing Abstract Data Type - Priority que, but I can't find out how to put values in correct order.
My structures:
typedef int kintyr;
typedef struct qElem {
struct qElem *prv;
kintyr *dat;
int *priority;
}qElem;
typedef struct que {
qElem *fr,*bk;
int cnt;
}que;
And now my main functions to implement a Priority que
First to create an empty PQ:
que *qNew()
{
que *q = malloc(sizeof(*q));
if (q==NULL)
return NULL;
q->fr = NULL;
q->bk = NULL;
q->cnt = 0;
qFault = 0;
return q;
}
This is function to add elements, but it isnt working
que *qEnq(que *q, kintyr *x, int *prrt)
{
que *zn=q;
qFault = 0;
if (q == NULL)
{
qFault = 1;
return q;
}
if (qCHKf(q) == 1)
{
qFault = 3;
return q;
}
qElem *new = malloc(sizeof(*new));
new->prv = NULL;
new->dat = x;
new->priority=prrt;
if (q->fr == NULL || prrt < q->fr->priority )
{
q->fr = new;
}
else
{
que *temp=q;
while(temp->fr!=NULL&&q->fr->priority <= prrt)
temp = temp->fr;
new->prv=temp->fr;
temp->fr=new;
//if (temp->bk != NULL)
//q->bk->prv = new;
q->bk = new; }}
q->cnt++;
return q;
}
}
Do you have any thoughts how can i fix this?

Resources