How to use Bubble sort in linked list without swapping the nodes? - linked-list

I am trying to use bubble sort to sort a linked list. Instead of swapping the nodes, why can't I swap the values of the nodes and produce the desired output? The below code was my approach.
struct node
{
int data;
struct node *next;
};
void sort_ll(struct node *head){
struct node *p1 = head;
struct node *p2 = NULL;
while(p1->next!=NULL){
p2 = p1;
int temp;
while(p2->next!=NULL){
if(p2->data>p1->data){
temp = p2->data;
p2->data = p1->data;
p1->data = temp;
}
p2 = p2->next;
}
p1 = p1->next;
}
print_ll(p1);
}

Related

how to copy env without leaks

Another Example For copy
But it makes segmentation faults
typedef struct s_env
{
char *key;
char *val;
struct s_env *next;
} t_env;
void env_tokenizing(char **envp, t_env **env)
{
int i;
char **_tok;
i = -1;
*env = malloc(sizeof(t_env));
if(!env)
return ;
while(envp[++i])
{
_tok = ft_split(envp[i], '=');
(*env)->key = _tok[0];
(*env)->val = _tok[1];
if (!envp[i + 1])
break;
(*env)->next = malloc(sizeof(t_env));
if(!(*env)->next)
return ;
env = &(*env)->next;
}
(*env)->next = NULL;
}
void env_tokenizing(char **envp, t_env **env)
{
int i;
char **_tok;
i = -1;
*env = malloc(sizeof(t_env));
if(!env)
return ;
while(envp[++i])
{
_tok = ft_split(envp[i], '=');
keyval((*env)->key, _tok[0]);
keyval((*env)->val, _tok[1]);
if (!envp[i + 1])
break;
(*env)->next = malloc(sizeof(t_env));
if(!(*env)->next)
return ;
env = &(*env)->next;
}
(*env)->next = NULL;
}
void keyval(char *locate, char *kv)
{
int i;
size_t len;
len = ft_strlen(kv);
locate = malloc(sizeof(char) * (len + 1));
if(!locate)
return ;
i = -1;
while(kv[++i])
locate[i] = kv[i];
locate[i] = '\0';
free(kv);
}
I'm going to copy environment variables from **envp argument from main without leaks. When I try to split every line in envp with = sign with [0] index i put the value to my env->key member, and a value of index [1] put to env->val member. But it leaves leaks behind. How can I add nodes to my env linked list withg key value members with **envp values. Here are two examples how I copied values.
In second example copy with keyval() function programm makes segmentation faluts.

Cs50 speller: not recognising any incorrect words

I'm currently working on the CS50 Speller function. I have managed to compile my code and have finished a prototype of the full program, however it does not work (it doesn't recognise any mispelled words). I am looking through my functions one at a time and printing out their output to have a look at what's going on inside.
// Loads dictionary into memory, returning true if successful else false
bool load(const char *dictionary)
{
char word[LENGTH + 1];
int counter = 0;
FILE *dicptr = fopen(dictionary, "r");
if (dicptr == NULL)
{
printf("Could not open file\n");
return 1;
}
while (fscanf(dicptr, "%s", word) != EOF)
{
printf("%s", word);
node *n = malloc(sizeof(node));
if (n == NULL)
{
unload();
printf("Memory Error\n");
return false;
}
strcpy(n->word, word);
int h = hash(n->word);
n->next = table[h];
table[h] = n;
amount++;
}
fclose(dicptr);
return true;
}
From what I can see this works fine. Which makes me wonder if the issue is with my check function as shown here:
bool check(const char *word)
{
int n = strlen(word);
char copy[n + 1];
copy[n] = '\0';
for(int i = 0; i < n; i++)
{
copy[i] = tolower(word[i]);
printf("%c", copy[i]);
}
printf("\n");
node *cursor = table[hash(copy)];
while(cursor != NULL)
{
if(strcasecmp(cursor->word, word))
{
return true;
}
cursor = cursor->next;
}
return false;
}
If someone with a keener eye can spy what is the issue I'd be very grateful as I'm stumped. The first function is used to load a the words from a dictionary into a hash table\linked list. The second function is supposed to check the words of a txt file to see if they match with any of the terms in the linked list. If not then they should be counted as incorrect.
This if(strcasecmp(cursor->word, word)) is a problem. From man strcasecmp:
Return Value
The strcasecmp() and strncasecmp() functions return an
integer less than, equal to, or greater than zero if s1 (or the first
n bytes thereof) is found, respectively, to be less than, to match, or
be greater than s2.
If the words match, it returns 0, which evaluates to false.

Find longest path between root node and any child

I have an array of elements, some of whom have children, who have children in turn and so on. I know the direct children of each element, and have a list of all descendents for each element.
-(NSMutableArray *)descendents:(Element *)e {
NSMutableArray * descendents = [NSMutableArray new];
for (NSString * uID in e.children){
[descendents addObject:uID];
Element * k = elements[uID][#"element"];
[descendents addObjectsFromArray:[self descendents:k]];
}
return descendents;
}
I can determine the root element by comparing the total number of descendents for each element. I can find the shortest route between the root and any given element given this:
-(int)find:(NSString *)uniqueID forElement:(Element *)e {
int distance = 0;
if ([e.children containsObject:uniqueID]){ //immediate child
distance ++; //increment distance
return distance; //return
} else if ([e.descendents containsObject:uniqueID]){ //grand child etc
distance ++;
for (NSString * uID in e.children){
Element * k = elements[uID][#"element"];
distance += [self find:uniqueID forElement:k];
return distance;
}
}
return 0;
}
What I want to do is find the longest distance between an element and the root. I'm thinking about going back up the tree from elements with zero children or adding an array of distances between elements in the mapping function. Struggling as to the cleanest approach - any ideas?
EDIT:
solution based on user3290797's answer below, tracking reference to max number of parents:
-(int)parentHeight:(NSString *)uID {
int maxHeight = 0;
Element * e = elements[uID][#"element"];
for (NSString * parentID in e.parents){
int height = [self parentHeight:parentID];
maxHeight = (height > maxHeight) ? height : maxHeight;
}
return maxHeight + 1;
}
The longest distance between an element and the root is called the height (or depth) of the tree.
One way to find it is to recursively traverse the tree and calculate the height of every node as the maximum of its children's heights plus one.
In pseudocode:
function height(node) {
maxChildHeight = 0
for(child in node.children) {
h = height(child)
if(h > maxChildHeight) {
maxChildHeight = h
}
}
return maxChildHeight + 1
}
If not a lot of nodes, calculate each distance and assign an ID for each , then check the longest of them , this is slow but works hahaha

Swap 2 nodes of a single linked list. i have the program. I need to ask where its wrong

I wrote the following program. The swap is working fine if i debug it. However i am not able to return the complete linked list. It is changing the head as well. what is wrong?
public static Node<Integer> swapElementsAtiAndj(Node<Integer> head, int i, int j)
{
Node<Integer> temp= head;
Node<Integer> prev1 = temp;
Node<Integer> prev2 = temp;
Node<Integer> toSwap1 = temp;
Node<Integer> toSwap2 = temp;
int count =0;
int pos1 =i;
int pos2 =j;
if(i>j) {
pos1 = j;
pos2 =i;
}
while (count !=pos1) {
prev1 = toSwap1;
toSwap1 = toSwap1.next;
prev2 = prev1;
toSwap2 = toSwap1;
count++;
}
while(count != pos2) {
prev2 = toSwap2;
toSwap2 = toSwap2.next;
count++;
}
temp.data = toSwap1.data;
temp.next = toSwap2.next;
toSwap2.next = toSwap1.next;
prev2.next = temp;
prev1.next = toSwap2;
return head;
}
Yes, your head is getting modified at
temp.next = toSwap2.next;
Because temp is pointing at head. Here is how you can fix it:
First of all,
prev2 = prev1;
toSwap2 = toSwap1;
can be written outside of while loop.
Now, after second while loop toSwap1 and toSwap2 are pointing at elements to be swapped.
// Swap prev
prev1.next = toSwap2;
prev2.next = toSwap1;
// Store toSwap2's next in temp
temp = toSwap2.next;
// Set toSwap2's next to toSwap1's next
toSwap2.next = toSwap1.next;
// Set toSwap1's next to old toSwap2's next (i.e temp)
toSwap1.next = temp;
// Return
return head;

How to define many struct elements in one go?

struct something
{
int a;
int b;
} this[10] = {1,2};
This bit of code is creating 10 elements with such a struct. But, only the first element a,b ints are set to 1,2.
Can we modify this code to set all 10 elements with these values?
struct something
{
int a;
int b;
} this[10] = {{1,2},{3,4},{5,6},{7,8},{9,10},{11,12},{13,14},{15,16},{17,18},{19,20}};
Or did you mean:
struct something
{
int a;
int b;
} this[10];
for (int i = 0; i < 10; i++) this[i] = {1,2};

Resources