Distance between two nodes in circular linked list - c

I want to find the distance between two nodes (number of node between them) in a circular linked list.
Where nodal is :
typedef struct node
{
int data;
struct node *next;
}nodal;
nodal *distance(nodal *start)
{
int n1,n2,d1=0,d2=0,c=0;
if(start==NULL)
{
printf("\nList is empty");
}
else
{
printf("\nEnter the fist node element : ");
scanf("%d",&n1);
printf("\nEnter the second node element : ");
scanf("%d",&n2);
nodal *ptr=start;
while(ptr->next!=start)
{
c++;
if(ptr->data==n1)
{
d1=c;
}
if(ptr->data==n2)
{
d2=c;
}
}
}
printf("The distance between two nodes is %d",(d2-d1));
return start;
}
I doesn't give any output.
Also suppose if circular list contains following data :
1,2,3,4,5,6,7,8,9
And if I give input
First node element as 9
Second node element as 4
Then this algorithm won't work.
Any suggestions for the change ?

Start counting when you find the first node and stop when you find the second one, something like:
int inc = 0, dist = 0;
if (n1 == n2) {
return 0;
}
node = start;
while (node) {
dist += inc;
if ((node->data == n1) || (node->data == n2)) {
if (inc++ == 1) return dist;
}
node = node->next;
if (node == start) break;
}
return 0;

First you have to go to the first element entered, in this process count will not be increased. Then start increasing to count until you reach the second element.
Code is below:
ptr=start;
while(ptr->data!=n1)
{
ptr=ptr->next;
}
//---now we have reached the first number----
while(ptr->data!=n2)
{
count++;
ptr=ptr->next;
}

There are multiple problems in your code:
the test for the end of the list prevents you from testing the last node.
you handle the case where n1 == n2 by returning 0, which may not be what is expected.
the distance between n1 and n2 will be negative if n2 appears before n1, which is incorrect: since the list is circular, if you keep scanning after n1, you will encounter n2 at a positive distance at most after wrapping over the first node.
Here is an alternate solution:
typedef struct node {
int data;
struct node *next;
} nodal;
nodal *distance(nodal *start) {
int n1, n2, d1 = 0, d2 = 0, length = 0;
if (start == NULL) {
printf("List is empty\n");
} else {
printf("\nEnter the fist node element : ");
if (scanf("%d", &n1) != 1) {
printf("invalid input\n");
return start;
}
printf("\nEnter the second node element : ");
if (scanf("%d", &n2) != 1) {
printf("invalid input\n");
return start;
}
nodal *ptr = start;
for (;;) {
length++;
if (ptr->data == n1 && !d1) {
d1 = length;
} else if (ptr->data == n2) {
if (d1) {
d2 = length;
break;
}
if (!d2)
d2 = length;
}
ptr = ptr->next;
if (ptr == start)
break;
}
}
if (d1 && d2) {
int dist = d2 - d1;
if (dist < 0)
dist += length;
printf("The distance between node(%d) and node(%d) is %d\n", d1, d2, dist);
} else {
if (d2)
printf("node(%d) not found\n", d1);
if (d1)
printf("node(%d) not found\n", d2);
}
return start;
}

Related

(C) Write doubles outside the stack

I am trying to write numbers from type double outside of the stack but I can't quite work it out how to do it. I have tried doing it with while loop and if statements, sometimes I get only zeros but most of the time I get nothing displayed. Thanks for helping in advance.
#include <stdio.h>
struct element
{
double data;
element * next;
};
element *top = NULL;
void Get(double &x)
{
element *p;
if(top == NULL)
{
printf("\nThe stack is empty!");
return;
}
x = top -> data;
p = top;
top = top -> next;
delete(p);
}
void Put(double x)
{
element *p;
p = new(element);
if(p == NULL)
{
printf("\nNOT enough memory!");
return;
}
p -> data = x;
p -> next = top;
top = p;
}
int main()
{
printf("Enter integers in stack. Enter 0 to end!\n");
double val;
double m;
do
{
printf("Enter number: ");
scanf("%lf", &val);
if(val >= 3697 && val <= 3698)
{
Put(val);
}
}
while(val != 0);
printf("\nStack contains: ");
while(top != NULL)
{
Get(val);
printf("%lf ", val);
}
return 0;
}

What is the best data structure to perform the following queries and why am I getting wrong result in mine

I need to build a data structure that:
learn x (insert x)
forget x (deletes x). if x not present, do nothing
decrease x n - decreases the count of x by n, if n >= count, then the node is simply deleted. and if x not present then do nothing
smaller_nums x - find number of nodes(counting their multiplicity) that are less than x
larger_nums x - similar to 4. but larger
asc k - print k'th element in ascending order(counting multiplicity), print -1 if k > total number of nodes
1≤ q ≤ 5*10^5
1≤ x ≤ 10^9
I have built an AVL tree for this, is there any better and simple data structure for this?
My code is working fine for the given input and output:
Input:
14
learn 5
learn 2
learn 7
learn 3
learn 2
smaller_nums 5
larger_nums 2
asc 2
decrease 2 1
asc 2
forget 7
larger_nums 2
forget 5
larger_nums 2
Output:
3
3
2
3
2
1
When I am submitting, I am passing 4/9 test cases.
I am getting wrong answer for 2 test cases and timeout for 3 testcases.
#include <stdio.h>
#include <stdlib.h>
long int N=0; //keeps count of total number nodes, this value is used in asc function only
// An AVL tree node
struct node {
long int key;
struct node* left;
struct node* right;
long int height;
long int count;
};
// A utility function to get height of the tree
long int height(struct node* N)
{
if (N == NULL)
return 0;
return N->height;
}
// A utility function to get maximum of two integers
long int max(long int a, long int b)
{
return (a > b) ? a : b;
}
/* Helper function that allocates a new node with the given key and
NULL left and right pointers. */
struct node* newNode(long int key)
{
struct node* node = (struct node*)
malloc(sizeof(struct node));
node->key = key;
node->left = NULL;
node->right = NULL;
node->height = 1; // new node is initially added at leaf
node->count = 1;
return (node);
}
// A utility function to right rotate subtree rooted with y
// See the diagram given above.
struct node* rightRotate(struct node* y)
{
struct node* x = y->left;
struct node* T2 = x->right;
// Perform rotation
x->right = y;
y->left = T2;
// Update heights
y->height = max(height(y->left), height(y->right)) + 1;
x->height = max(height(x->left), height(x->right)) + 1;
// Return new root
return x;
}
// A utility function to left rotate subtree rooted with x
// See the diagram given above.
struct node* leftRotate(struct node* x)
{
struct node* y = x->right;
struct node* T2 = y->left;
// Perform rotation
y->left = x;
x->right = T2;
// Update heights
x->height = max(height(x->left), height(x->right)) + 1;
y->height = max(height(y->left), height(y->right)) + 1;
// Return new root
return y;
}
// Get Balance factor of node N
long int getBalance(struct node* N)
{
if (N == NULL)
return 0;
return height(N->left) - height(N->right);
}
struct node* insert(struct node* node, long int key)
{
/* 1. Perform the normal BST rotation */
if (node == NULL)
{ N++;
return (newNode(key));
}
// If key already exists in BST, increment count and return
if (key == node->key) {
(node->count)++;
N++;
return node;
}
/* Otherwise, recur down the tree */
if (key < node->key)
node->left = insert(node->left, key);
else
node->right = insert(node->right, key);
/* 2. Update height of this ancestor node */
node->height = max(height(node->left), height(node->right)) + 1;
/* 3. Get the balance factor of this ancestor node to check whether
this node became unbalanced */
long int balance = getBalance(node);
// If this node becomes unbalanced, then there are 4 cases
// Left Left Case
if (balance > 1 && key < node->left->key)
return rightRotate(node);
// Right Right Case
if (balance < -1 && key > node->right->key)
return leftRotate(node);
// Left Right Case
if (balance > 1 && key > node->left->key) {
node->left = leftRotate(node->left);
return rightRotate(node);
}
// Right Left Case
if (balance < -1 && key < node->right->key) {
node->right = rightRotate(node->right);
return leftRotate(node);
}
/* return the (unchanged) node pointer */
return node;
}
/* Given a non-empty binary search tree, return the node with minimum
key value found in that tree. Note that the entire tree does not
need to be searched. */
struct node* minValueNode(struct node* node)
{
struct node* current = node;
/* loop down to find the leftmost leaf */
while (current->left != NULL)
current = current->left;
return current;
}
struct node* forgetNode(struct node* root, long int key)
{
// STEP 1: PERFORM STANDARD BST DELETE
if (root == NULL)
return root;
// If the key to be deleted is smaller than the root's key,
// then it lies in left subtree
if (key < root->key)
root->left = forgetNode(root->left, key);
// If the key to be deleted is greater than the root's key,
// then it lies in right subtree
else if (key > root->key)
root->right = forgetNode(root->right, key);
// if key is same as root's key, then This is the node
// to be deleted
else {
N += -(root->count);
// If key is present more than once, simply decrement
// count and return
// Else, delete the node
// node with only one child or no child
if ((root->left == NULL) || (root->right == NULL)) {
struct node* temp = root->left ? root->left : root->right;
// No child case
if (temp == NULL) {
temp = root;
root = NULL;
}
else // One child case
*root = *temp; // Copy the contents of the non-empty child
free(temp);
}
else {
// node with two children: Get the inorder successor (smallest
// in the right subtree)
struct node* temp = minValueNode(root->right);
// Copy the inorder successor's data to this node and update the count
root->key = temp->key;
root->count = temp->count;
temp->count = 1;
// Delete the inorder successor
root->right = forgetNode(root->right, temp->key);
}
}
// If the tree had only one node then return
if (root == NULL)
return root;
// STEP 2: UPDATE HEIGHT OF THE CURRENT NODE
root->height = max(height(root->left), height(root->right)) + 1;
// STEP 3: GET THE BALANCE FACTOR OF THIS NODE (to check whether
// this node became unbalanced)
long int balance = getBalance(root);
// If this node becomes unbalanced, then there are 4 cases
// Left Left Case
if (balance > 1 && getBalance(root->left) >= 0)
return rightRotate(root);
// Left Right Case
if (balance > 1 && getBalance(root->left) < 0) {
root->left = leftRotate(root->left);
return rightRotate(root);
}
// Right Right Case
if (balance < -1 && getBalance(root->right) <= 0)
return leftRotate(root);
// Right Left Case
if (balance < -1 && getBalance(root->right) > 0) {
root->right = rightRotate(root->right);
return leftRotate(root);
}
return root;
}
struct node* decreaseNode(struct node* root, long int key, long int n)
{
// STEP 1: PERFORM STANDARD BST DELETE
if (root == NULL)
return root;
// If the key to be deleted is smaller than the root's key,
// then it lies in left subtree
if (key < root->key)
root->left = decreaseNode(root->left, key, n);
// If the key to be deleted is greater than the root's key,
// then it lies in right subtree
else if (key > root->key)
root->right = decreaseNode(root->right, key, n);
// if key is same as root's key, then This is the node
// to be deleted
else {
// If key is present more than once, simply decrement
// count and return
if (root->count > 1 && n < root->count) {
(root->count) += -n;
N += -n;
return root;
}
// Else, delete the node
// node with only one child or no child
N += -(root->count);
if ((root->left == NULL) || (root->right == NULL)) {
struct node* temp = root->left ? root->left : root->right;
// No child case
if (temp == NULL) {
temp = root;
root = NULL;
}
else // One child case
*root = *temp; // Copy the contents of the non-empty child
free(temp);
}
else {
// node with two children: Get the inorder successor (smallest
// in the right subtree)
struct node* temp = minValueNode(root->right);
// Copy the inorder successor's data to this node and update the count
root->key = temp->key;
root->count = temp->count;
temp->count = 1;
// Delete the inorder successor
root->right = decreaseNode(root->right, temp->key, n);
}
}
// If the tree had only one node then return
if (root == NULL)
return root;
// STEP 2: UPDATE HEIGHT OF THE CURRENT NODE
root->height = max(height(root->left), height(root->right)) + 1;
// STEP 3: GET THE BALANCE FACTOR OF THIS NODE (to check whether
// this node became unbalanced)
long int balance = getBalance(root);
// If this node becomes unbalanced, then there are 4 cases
// Left Left Case
if (balance > 1 && getBalance(root->left) >= 0)
return rightRotate(root);
// Left Right Case
if (balance > 1 && getBalance(root->left) < 0) {
root->left = leftRotate(root->left);
return rightRotate(root);
}
// Right Right Case
if (balance < -1 && getBalance(root->right) <= 0)
return leftRotate(root);
// Right Left Case
if (balance < -1 && getBalance(root->right) > 0) {
root->right = rightRotate(root->right);
return leftRotate(root);
}
return root;
}
// Convinience function to travers the tree in ascending order
void inOrder(struct node* root)
{
if (root != NULL) {
inOrder(root->left);
printf("%ld(%ld) ", root->key, root->count);
inOrder(root->right);
}
}
// Find out number of larger nodes
void largerNums(struct node* root, long int key, long int* lnums){
if (root == NULL)
return;
if (key < root->key){
(*lnums) += root->count;
largerNums(root->right, key, lnums);
largerNums(root->left, key, lnums);
}
else if (key >= root->key)
largerNums(root->right, key, lnums);
return;
}
// Find out number of smaller nodes
void smallerNums(struct node* root, long int key, long int* snums){
if (root == NULL)
return;
if (key <= root->key){
smallerNums(root->left, key, snums);
}
else if (key > root->key){
(*snums) += root->count;
smallerNums(root->left, key, snums);
smallerNums(root->right, key, snums);
}
return;
}
// Prints k'th element in ascending order
void asc(struct node* root, long int key, long int* cnt){
if (root != NULL) {
asc(root->left, key, cnt);
int i;
for(i=1; i <= (root->count); ++i){
(*cnt)++;
if(*cnt == key){
printf("%ld\n", root->key);
return;
}
}
asc(root->right, key, cnt);
}
}
// Function to compare strings
int myStrCompare(char a[], char b[]){
int c = 0;
while (a[c] == b[c]) {
if (a[c] == '\0' || b[c] == '\0')
break;
c++;
}
if (a[c] == '\0' && b[c] == '\0')
return 0;
else
return -1;
}
// Function to know what command entered by user
int myCompare(char *str){
if(myStrCompare(str, "learn") == 0)
return 1;
else if(myStrCompare(str, "forget") == 0)
return 2;
else if(myStrCompare(str, "decrease") == 0)
return 3;
else if(myStrCompare(str, "smaller_nums") == 0)
return 4;
else if(myStrCompare(str, "larger_nums") == 0)
return 5;
else if(myStrCompare(str, "asc") == 0)
return 6;
return -1;
}
/* Driver program to test above function*/
int main()
{
long int i, q, x, n, lnums, snums, cnt;
int choice;
char input[100];
struct node* root= NULL;
scanf("%ld", &q);
//printf("%s", input);
for(i=1; i<=q; ++i){
scanf("%s", input);
//printf("%s", input);
choice = myCompare(input);
//printf("\n%d", choice);
switch(choice){
case 1: scanf("%ld", &x);
//printf("\nEntered x\n: %d", x);
root = insert(root, x);
/* printf("\n");
inOrder(root);
printf("\n");*/
break;
case 2: scanf("%ld", &x);
//printf("\nEntered x\n: %d", x);
root = forgetNode(root, x);
/*printf("\n");
inOrder(root);
printf("\n");*/
break;
case 3: scanf("%ld%ld", &x, &n);
//printf("\nEntered x\n: %d", x);
if(n < 1){
break;
}else{
root = decreaseNode(root, x, n);
}
/* printf("\n");
inOrder(root);
printf("\n");*/
break;
case 4: scanf("%ld", &x);
//printf("\nEntered x\n: %d", x);
snums = 0;
smallerNums(root, x, &snums);
/*printf("\n");
inOrder(root);
printf("\n");*/
printf("%ld\n", snums);
break;
case 5: scanf("%ld", &x);
//printf("\nEntered x\n: %d", x);
lnums = 0;
largerNums(root, x, &lnums);
/*printf("\n");
inOrder(root);
printf("\n");*/
printf("%ld\n", lnums);
break;
case 6: scanf("%ld", &x);
if(x > N){
printf("%d\n", -1);
break;
}else{
//printf("\nEntered x\n: %d", x);
cnt=0;
asc(root, x, &cnt);
}
/*printf("\n");
inOrder(root);
printf("\n");*/
break;
}
}
/*root = insert(root, 5);
root = insert(root, 2);
root = insert(root, 7);
root = insert(root, 3);
root = insert(root, 2);
smallerNums(root, 5, &s);
printf("\n%d\n", s);
largerNums(root, 2, &l);
printf("%d\n", l);
inOrderK(root, 2, &cnt); cnt = 0;
root = decreaseNode(root, 2, 1);
inOrderK(root, 2, &cnt); cnt = 0;
root = forgetNode(root, 7);
l=0;
largerNums(root, 2, &l);
printf("%d\n", l);
root = forgetNode(root, 5);
l=0;
largerNums(root, 2, &l);
printf("%d\n", l);
inOrder(root);
l=0;
largerNums(root, 1, &l);
printf("\n%d\n", l);
*/
return 0;
}
I have looked over my code multiple times and unable to figure out what is wrong
Try to do this in log(n) time
Put left_count and right_count in node

Tic-Tac-Toe user input looping endlessly when alphabetical character entered

So I am making a tic tac toe game in C and I am having a problem where I am asking the user to undo their move by pressing 2. Each time it is their turn, they can either undo a move or continue to select there next turn by selecting another key.
It works how it should but I have a problem where if the user enters an alphabetical character, the program just repeatedly loops through saying that this is not a number when it checks my GetHumanMove function. Does anyone know how to make it stop doing this and just say this is not a number once without it looping the program?
Here's my code:
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <conio.h>
#include <windows.h>
//Tic-Tac-Toe game in C
//20/03/2019
//5x5 Board with 4 in a row to win. Also has playable AI that randomly blocks human moves.
//Also has replay function using a doubly linked list
/*
int board[49] = {
;,;, ;, ;, ;, ;, ;,
;,1, 2, 3, 4, 5 ,;,
;,6, 7, 8, 9, 10,;,
;,11,12,13,14,15,;,
;,16,17,18,19,20,;,
;,21,22,23,24,25,;,
;,;, ;, ;, ;, ;, ;,
}
*/
struct node
{
int side;
int move;
int place;
struct node * prev;
struct node * next;
};
void append(struct node **, int, int, int);
void display(struct node *);
void delete(struct node **, int);
//Constants of pieces, border and empty places
enum { NOUGHTS, CROSSES, BORDER, EMPTY };
//Constants for human/computer win or draw
enum { HUMANWIN, COMPWIN, DRAW };
const int directions[4] = { 1, 7, 6, 8 };
int moveCount = 0;
//Values of original places to play
const int ConvertTo49[25] = {
8, 9, 10,11,12,
15,16,17,18,19,
22,23,24,25,26,
29,30,31,32,33,
36,37,38,39,40
};
void append(struct node ** list, int side, int move, int place)
{
struct node *temp , *current = *list;
if(*list == NULL)
{
*list = (struct node *) malloc(sizeof(struct node));
(*list) -> prev = NULL;
(*list) -> side = side;
(*list) -> move = move;
(*list) -> place = place;
(*list) -> next = NULL;
}
else
{
while(current -> next != NULL)
current = current -> next;
temp = (struct node *) malloc(sizeof(struct node));
temp -> side = side;
temp -> move = move;
temp -> place = place;
temp -> next = NULL;
temp -> prev = current;
current -> next = temp;
}
}
void delete(struct node ** list, int num)
{
struct node *temp = *list;
while(temp != NULL)
{
if(temp -> move == num)
{
if(temp == *list)
{
*list = (*list) -> next;
(*list) -> prev = NULL;
}
else
{
if(temp -> next == NULL)
temp -> prev -> next = NULL;
else
{
temp -> prev -> next = temp -> next;
temp -> next -> prev = temp -> prev;
}
free(temp);
}
return ;
}
temp = temp -> next;
}
printf("Element %d not found in the supplied list \n\n", num);
}
//Loop through a direction until a border square is hit
int GetNumForDir(int startSq, const int dir, const int *board, const int us)
{
int found = 0;
while(board[startSq] != BORDER)
{
if(board[startSq] != us)
{
break;
}
found++;
startSq += dir;
}
return found;
}
//Loop through directions and find four in a row
int FindFourInARow(const int *board, const int ourIndex, const int us)
{
int dirIndex = 0;
int dir = 0;
int countFour = 1;
for(dirIndex = 0; dirIndex < 4; ++dirIndex)
{
dir = directions[dirIndex];
countFour += GetNumForDir(ourIndex + dir, dir, board, us);
countFour += GetNumForDir(ourIndex + dir * -1, dir * -1, board, us);
if(countFour == 4)
{
break;
}
countFour = 1;
}
return countFour;
}
//Set up board structure
void InitialiseBoard(int *board)
{
//index variable
int index;
//set whole board to border squares initially
for(index = 0; index < 49; ++index)
{
board[index] = BORDER;
}
//Set up empty squares for placing pieces
for(index = 0; index < 25; ++index)
{
board[ConvertTo49[index]] = EMPTY;
}
}
//Print the board
void PrintBoard(const int *board)
{
//index variable
int index;
//Set pieces and places
char pceChars[] = "OX| ";
printf("\n\n\n");
//Loop through and only draw the actual playable squares, leaving out the border squares
for(index = 0; index < 25; ++index)
{
//Put lines inbetween places
if(index==1 || index==2 || index==3 || index==4 ||
index==6 || index==7 || index==8 || index==9 ||
index==11 || index==12 || index==13 || index==14 ||
index==16 || index==17 || index==18 || index==19 ||
index==21 || index==22 || index==23 || index==24)
{
printf(" |");
}
//Put space at start to space out board from edge of screen
if(index==0)
{
printf(" ");
}
//Print new line every 5 places
if(index!= 0 && index==5 || index==10 || index==15 || index==20)
{
printf("\n");
printf(" -------------------");
printf("\n");
printf(" ");
}
//Print each playable piece
printf(" %c", pceChars[board[ConvertTo49[index]]]);
}
printf("\n\n");
}
//Check if board has empty spaces
int HasEmpty(const int *board)
{
int index;
for(index = 0; index < 25; ++index)
{
if(board[ConvertTo49[index]] == EMPTY) return 1;
}
return 0;
}
//Function for making move of current player
void MakeMove(int *board, const int sq, const side)
{
//set board place that either player decides
board[sq] = side;
}
void UndoMove(int *board, int sq, int side)
{
//set board place that either player decides
board[sq] = side;
}
//Help the computer find a winning move
int GetWinningMove(int *board, const int side)
{
int ourMove = -1;
int winFound = 0;
int index = 0;
for(index = 0; index < 25; ++index)
{
if(board[ConvertTo49[index]] == EMPTY)
{
ourMove = ConvertTo49[index];
board[ourMove] = side;
if(FindFourInARow(board, ourMove, side) == 4)
{
winFound = 1;
}
board[ourMove] = EMPTY;
if(winFound == 1)
{
return ourMove;
}
ourMove = -1;
};
}
return ourMove;
}
//Get computer player move
int GetComputerMove(int *board, const int side)
{
int index;
int numFree = 0;
int availableMoves[25];
int randMove = 0;
//Set random number to randomly run a function
int randFunction = 0;
randFunction = (rand() % 2);
//Go for the winning move
randMove = GetWinningMove(board, side);
if(randMove != -1)
{
return randMove;
}
//If random function is 1, stop any winning move from the human
if(randFunction == 1)
{
randMove = GetWinningMove(board, side ^ 1);
if(randMove != -1)
{
return randMove;
}
}
randMove = 0;
//Loop through all squares and put piece in random place
for(index = 0; index < 25; ++index)
{
if(board[ConvertTo49[index]] == EMPTY)
{
availableMoves[numFree++] = ConvertTo49[index];
};
}
randMove = (rand() % numFree);
return availableMoves[randMove];
}
//Get human player move
int GetHumanMove(const int *board)
{
//Array for user input
int userInput;
char term;
//Start moveOK at 0
int moveOK = 0;
int move = -1;
//Loop through until move being made is valid
while(moveOK == 0)
{
printf("\n");
//Ask user for input of 1-9
printf("Please enter a place on the board to make your move, from 1 to 25: ");
//Make sure that user doesnt enter long string with number on the end that eventaully passes tests in the while loop
scanf("%d%c", &userInput, &term);
if(term != '\n')
{
move = -1;
printf("This is not a number\n");
continue;
}
//Check if input is in proper range
if(userInput < 1 || userInput > 25)
{
move = -1;
printf("Invalid Range\n");
continue;
}
//decrement move to get the array location of the playable places
userInput--;
//Check if place selected is already taken
if(board[ConvertTo49[userInput]] != EMPTY)
{
move = -1;
printf("Square not available\n");
continue;
}
//Set move ok to 1 after passing all the tests
moveOK = 1;
}
//Print move being made and return it
printf("\nHuman making Move at square: %d\n",(userInput+1));
return ConvertTo49[userInput];
}
//Run Game function
void RunGame()
{
struct node *list;
list = NULL;
//Display
printf("\n\n Noughts And Crosses Game:");
printf("\n =========================");
//game over variable
int gameOver = 0;
//Start on noughts side
int side = NOUGHTS;
//Record last move
int lastMoveMade = 0;
//Create new board
int board[49];
//Count of first move
int initialMove = 0;
//Initialise the Board
InitialiseBoard(&board[0]);
//Print the board to screen
PrintBoard(&board[0]);
//While game isn't over
while(!gameOver)
{
initialMove++;
//Human
if(side==NOUGHTS)
{
//Ask to undo move after first move played
if(initialMove > 1)
{
while(list -> prev != NULL)
list = list -> prev;
int undo;
printf("\n\nWould you like to undo your move? \nEnter 2 to undo or any other key/s to continue: ");
scanf("%d", &undo);
if( undo == 2)
{
while(list -> next != NULL)
list = list -> next;
char pceChars[] = "OX| ";
//printf(" %c", pceChars[board[ConvertTo49[index]]]);
int count = 2;
while(count != 0)
{
UndoMove(&board[0], list -> place, EMPTY);
list = list -> prev;
delete(&list, list -> next -> move);
moveCount--;
count--;
}
PrintBoard(&board[0]);
}
}
//Make new move for human
lastMoveMade = GetHumanMove(&board[0]);
MakeMove(&board[0], lastMoveMade, side);
moveCount++;
int humanMove;
//Find the position the computer is making on the 5x5 board
for(humanMove = 0; humanMove < 25; ++humanMove)
{
if(ConvertTo49[humanMove] == lastMoveMade)
{
break;
}
}
append(&list, 0, moveCount, lastMoveMade);
side = CROSSES;
}
//Computer
else
{
//Make move for computer
lastMoveMade = GetComputerMove(&board[0], side);
MakeMove(&board[0], lastMoveMade, side);
int compMove;
//Find the position the computer is making on the 5x5 board
for(compMove = 0; compMove < 25; ++compMove)
{
if(ConvertTo49[compMove] == lastMoveMade)
{
break;
}
}
printf("\nComputer making move at square: %d", compMove+1);
moveCount++;
append(&list, 1, moveCount, lastMoveMade);
side = NOUGHTS;
PrintBoard(&board[0]);
}
//If three in a row exists, game over
if(FindFourInARow(board, lastMoveMade, side ^ 1) == 4)
{
gameOver = 1;
if(side == NOUGHTS)
{
printf("\nGame Over!\n");
printf("Computer Wins! :(\n");
}
else
{
PrintBoard(&board[0]);
printf("\nGame Over!\n");
printf("Human Wins! :D\n");
}
}
//If no more moves, game is a draw
if(!HasEmpty(board))
{
PrintBoard(&board[0]);
printf("\n\nGame Over!\n");
gameOver = 1;
printf("It's a draw! :/\n");
}
}
/*
*
* Match Replay
*
*/
int answer;
printf("\n\nWould you like to replay the match? \nEnter 1 to replay or any other key/s to quit: ");
scanf("%d", &answer);
if(answer == 1)
{
InitialiseBoard(&board[0]);
while ( list != NULL )
{
MakeMove(&board[0], list -> place, list -> side);
PrintBoard(&board[0]);
char who[7];
if(list -> side == 0)
{
strcpy(who, "NOUGHTS");
//who = "NOUGHTS";
}
else
{
strcpy(who, "CROSSES");
//who = "CROSSES";
}
int moveMade;
//Find the position the computer is making on the 5x5 board
for(moveMade = 0; moveMade < 25; ++moveMade)
{
if(ConvertTo49[moveMade] == list -> place)
{
break;
}
}
printf ("\nMove:%2d Side:%8s Place: %d\n", list -> move, who, moveMade+1);
Sleep(2000);
list = list -> next ;
}
}
else
{
printf("\nGood Game! See ya!\n");
getch();
}
}
int main()
{
//Create random number
srand(time(NULL));
//Call Run Game to play
RunGame();
return 0;
}
Input that doesn't match your format doesn't get consumed by scanf. It remains in the input stream. So when you type a letter it fails to match the number you wanted %d and stays in the input stream.
scanf("%d%c", &userInput, &term);
Instead of scanf, it would be simpler to use getline to consume the entire line of input. And then parse the result with sscanf (the string-based version of the function) or another method.
char *line = NULL;
size_t len = 0;
while ((read = getline(&line, &len, stdin)) != -1) {
// Do something with line
int scanned = sscanf(line, "%d%c", &userInput);
if (scanned == EOF || scanned != 2) {
printf("Line failed to match\n");
}
}
Just read the manual page:
The format string consists of a sequence of directives which describe
how to process the sequence of input characters. If processing of a
directive fails, no further input is read, and scanf() returns. A
"failure" can be either of the following: input failure, meaning that
input characters were unavailable, or matching failure, meaning that
the input was inappropriate (see below).
You do not check the return value of scanf(). So you try to scan the same non-digit as digit all the time.

Editing a List Program in C

I am trying to edit a program I made a year ago, but it seems I am failing somewhere because I can't get the result I want. I want to make the program to sort the numbers from low to high and the user should enter numbers until 0 is pressed. Would love ot get some help from someone advanced!
#include <stdio.h>
#include <stdlib.h>
struct node
{
int data;
struct node *next;
};
struct node* List;
void Add(struct node* p, int d)
{
struct node* q;
q = malloc(sizeof(struct node));
if (q == NULL)
printf("Not enaugh memory!");
else{
q->data = d;
if (List == NULL || List->data < d)
{
q->next = List;
List = q;
} else {
struct node *ptr = List;
while ((ptr->next != NULL) && (ptr->next->data>d)){
ptr = ptr->next;
}
q->next = ptr->next;
ptr->next = q;
}
}
}
int main()
{
int n, i, a;
printf("How many numbers are you going to enter? ");
scanf("%d", &n);
for (i = 1; i <= n; i++)
{
printf("\nEnter a number: ");
scanf("%d", &a);
Add(List, a);
}
printf("\nEntered and sorted numbers are: ");
struct node *ptr = List;
while (ptr != NULL)
{
printf("%d ", ptr->data);
ptr = ptr->next;
}
printf("\n\n");
system("PAUSE");
return 0;
}
Just change to line
if (List == NULL || List->data < d)
to
if (List == NULL || List->data > d)
And change the line
while ((ptr->next != NULL) && (ptr->next->data>d)){
to
while ((ptr->next != NULL) && (ptr->next->data<d)){
And you have not added 0 check.Please add that, rest is fine. For this modify the for loop with this one
//printf("How many numbers are you going to enter? ");
//scanf("%d", &n);
for (;;)
{
printf("\nEnter a number: ");
scanf("%d", &a);
if(a == 0)
break;
Add(List, a);
}

C: Structured Data Types - Linked Lists

Here is my code:
#include<stdio.h>
#include<stdlib.h>
typedef struct list_node
{
int data;
struct list_node *next;
} node;
node *head,*temp;
int counter;
void display_menu();
char get_choice();
void process(char option);
void Insert_first();
void Print_first();
void Delete_first();
void Delete_end(); // Problem
void Insert_end(); // Problem
void Search();
int main()
{
char choice;
display_menu();
do
{
choice=get_choice();
process(choice);
} while(choice!='J');
return 0;
}
void display_menu()
{
printf("What do you want do do?\n");
printf("A. Insert a node at the beginning of the list\n");;
printf("B. Delete the first node of the list\n");
printf("C. Print list\n");
printf("D. Insert end\n");
printf("E. Delete the last node of the list\n");
printf("F. Search\n");
}
char get_choice()
{
char select;
printf("Enter your choice:\t");
scanf("%c",&select);
getchar();
printf("\n");
return select;
}
void process(char option)
{
switch(option)
{
case 'A': Insert_first();break;
case 'B': Delete_first();break;;
case 'C': Print_first();break;
case 'D': Insert_end();break;
case 'E': Delete_end();break;
case 'F': Search(); break;
default:
printf("Invalid input!\n\n");
}
}
void Search()
{
node *a;
node *b;
int i, j;
a=head;
b=head;
for(i = 1; i < counter - 1; ++i){
a = a -> next;
for(j = i + 1; j < counter; ++j){
b = b -> next;
if((a -> data) == (b -> data)){
printf("0\n");
}
else{
printf("1\n");
}
}
}
counter++;
}
void Insert_first()
{
temp=(node *)malloc(sizeof(node));
printf("Enter a number:\t");
scanf("%d",&(temp->data));
getchar();
printf("\n");
temp->next=head;
head=temp;
counter++;
}
void Insert_end()
{
temp=(node *)malloc(sizeof(node));
node *x;
int y;
printf("Enter a number:\t");
scanf("%d",&(temp->data));
getchar();
printf("\n");
x=head;
for(y = 1; y < counter; ++y){
x=x->next;
}
temp->next=x->next;
x->next = temp;
counter++;
}
void Print_first()
{
if(head==NULL)
{
printf("The list is empty\n");
}
else
{
temp=head;
printf("-------------------------------------------------\n");
do
{
printf("\t%d\t", temp->data);
temp=temp->next;
} while(temp!=NULL);
printf("\n");
printf("-------------------------------------------------\n\n");
}
}
void Delete_first()
{
if(head==NULL)
{
printf("\nThe list is empty\n");
}
else
{
temp=head;
head=temp->next;
free(temp);
counter--;
}
}
void Delete_end()
{
node *x, *z;
int y;
if(head == NULL)
printf("The list is empty");
else{
x=head;
for(y = 1; y < counter; ++y){
x=x->next;
}
z=x;
x=x->next;
free(z);
counter--;
}
}
I have two problems to solve:
The Delete_end() function;
The Search() function.
I want the Delete_end() function to act as Delete_first() function, but instead of deleting the FIRST node and deallocates its space, it does these to the END node. I tried to code these functions, but it didnt return what I want it to be.
If we run the codes, and Enter the Following:
As you notice when I delete the first node (Switch Choice: B), the list from
--------------------------------
4 3 2
--------------------------------
becomes
--------------------------------
3 2
--------------------------------
Thus, it deletes the first node and deallocates the space. Now when I delete the end node (Switch Choice: E) and print the list (Switch Choice: C), the list becomes
--------------------------------
3 135704608
--------------------------------
I think the number 135704608 is the location in the memory. So what happen here is it didnt delete the last node and deallocates it but instead returns 135704608. I hope you can help me with that.
Second function is the Search(), this function should return 0 if the number is already in the list, else 1 is returned. Here is the Search() function from the above codes:
void Search()
{
node *a;
node *b;
int i, j;
a=head;
b=head;
for(i = 1; i < counter - 1; ++i){
a = a -> next;
for(j = i + 1; j < counter; ++j){
b = b -> next;
if((a -> data) == (b -> data)){
printf("0\n");
}
else{
printf("1\n");
}
}
}
counter++;
}
Any help is greatly appreciated!
For delete at end, your code finds the next to last element and does this:
z=x; // save next to last as z
x=x->next; //set last as x
free(z); // free next to last
Instead, I think you want to do something more like this:
free(x->next); // free last elem
x->next = NULL; // next to last now points to NULL, meaning x is now the last element
The problem with your search function is that you never check the first element! You should do your if comparison before you do b = b -> next and then do a = a -> next after the inner for loop - otherwise the head will never be compared to anything, and nothing will be compared to the element immediately after it.

Resources