assignment 1 problem 1
This commit is contained in:
5
assignment1/problem1/Makefile
Normal file
5
assignment1/problem1/Makefile
Normal file
@@ -0,0 +1,5 @@
|
|||||||
|
EXEC = list
|
||||||
|
SRC = $(wildcard *.c)
|
||||||
|
|
||||||
|
$(EXEC): $(SRC)
|
||||||
|
gcc -o $@ $^ -Wall
|
||||||
195
assignment1/problem1/list.c
Normal file
195
assignment1/problem1/list.c
Normal file
@@ -0,0 +1,195 @@
|
|||||||
|
/*
|
||||||
|
* Author: Walter
|
||||||
|
* Student ID: 1930006025
|
||||||
|
* Assignment_1_problem_1
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include "list.h"
|
||||||
|
#include <stdbool.h>
|
||||||
|
#include <stdio.h>
|
||||||
|
#include <stdlib.h>
|
||||||
|
|
||||||
|
// Write all your functions here.
|
||||||
|
bool IsEmpty(Node *head) {
|
||||||
|
if (head == NULL) {
|
||||||
|
return true;
|
||||||
|
} else {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/* code from pdf */
|
||||||
|
Node *InsertNode(Node **phead, int index, double x) {
|
||||||
|
if (index < 0)
|
||||||
|
return NULL;
|
||||||
|
int currIndex = 1;
|
||||||
|
Node *currNode = *phead;
|
||||||
|
while (currNode != NULL && index > currIndex) {
|
||||||
|
currNode = currNode->next;
|
||||||
|
currIndex++;
|
||||||
|
}
|
||||||
|
if (index > 0 && currNode == NULL)
|
||||||
|
return NULL;
|
||||||
|
Node *newNode = (Node *)malloc(sizeof(Node));
|
||||||
|
newNode->data = x;
|
||||||
|
if (index == 0) {
|
||||||
|
newNode->next = *phead;
|
||||||
|
*phead = newNode;
|
||||||
|
} else {
|
||||||
|
newNode->next = currNode->next;
|
||||||
|
currNode->next = newNode;
|
||||||
|
}
|
||||||
|
return newNode;
|
||||||
|
}
|
||||||
|
|
||||||
|
int FindNode(Node *head, double x) {
|
||||||
|
int position;
|
||||||
|
Node *pnode;
|
||||||
|
|
||||||
|
/* position start from 1 */
|
||||||
|
for (pnode = head, position = 1; pnode; pnode = pnode->next, position++) {
|
||||||
|
if (pnode->data == x) {
|
||||||
|
return position;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
int DeleteNode(Node **phead, double x) {
|
||||||
|
/* position start from 1 */
|
||||||
|
int position;
|
||||||
|
Node *pnode;
|
||||||
|
Node *delNode;
|
||||||
|
|
||||||
|
/* if delete the first node */
|
||||||
|
if ((*phead)->data == x) {
|
||||||
|
delNode = *phead;
|
||||||
|
*phead = (*phead)->next;
|
||||||
|
free(delNode);
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* if not the first node */
|
||||||
|
for (pnode = *phead, position = 2; pnode->next;
|
||||||
|
pnode = pnode->next, position++) {
|
||||||
|
/* loop for pnode->next->data == x */
|
||||||
|
if (pnode->next->data == x) {
|
||||||
|
/* delete node */
|
||||||
|
delNode = pnode->next;
|
||||||
|
pnode->next = pnode->next->next;
|
||||||
|
free(delNode);
|
||||||
|
return position;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/* if node not found, return 0 */
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
void DisplayList(Node *head) {
|
||||||
|
Node *pnode;
|
||||||
|
/* loop for each node */
|
||||||
|
for (pnode = head; pnode; pnode = pnode->next) {
|
||||||
|
printf("%f ", pnode->data);
|
||||||
|
}
|
||||||
|
/* new line at the end */
|
||||||
|
printf("\n");
|
||||||
|
}
|
||||||
|
|
||||||
|
void DestroyList(Node *head) {
|
||||||
|
Node *pnode = head;
|
||||||
|
Node *delNode;
|
||||||
|
/* loop for each node */
|
||||||
|
while (pnode) {
|
||||||
|
/* store the tmp node */
|
||||||
|
delNode = pnode;
|
||||||
|
pnode = pnode->next;
|
||||||
|
free(delNode);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void InverstNode(Node **head) {
|
||||||
|
/* empty list */
|
||||||
|
if (*head == NULL) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* only one node in list */
|
||||||
|
if ((*head)->next == NULL) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* reverse Node */
|
||||||
|
Node *a, *b, *c;
|
||||||
|
a = NULL;
|
||||||
|
b = *head;
|
||||||
|
c = (*head)->next;
|
||||||
|
|
||||||
|
/* when c == NULL, b is the end of linked list */
|
||||||
|
while (c) {
|
||||||
|
/* reverse node */
|
||||||
|
b->next = a;
|
||||||
|
/* move a, b, c forward */
|
||||||
|
a = b;
|
||||||
|
b = c;
|
||||||
|
c = c->next;
|
||||||
|
}
|
||||||
|
/* finanl step */
|
||||||
|
b->next = a;
|
||||||
|
/* reset head */
|
||||||
|
*head = b;
|
||||||
|
}
|
||||||
|
|
||||||
|
void RemoveDuplicates(Node **head) {
|
||||||
|
Node *newHead = NULL, *currNode = *head;
|
||||||
|
double oldValue;
|
||||||
|
int position;
|
||||||
|
|
||||||
|
/* empty list, no need to do anything */
|
||||||
|
if ((*head) == NULL) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* only one node in the list, no need to do anything */
|
||||||
|
if ((*head)->next == NULL) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* loop until currNode point at NULL */
|
||||||
|
while (currNode) {
|
||||||
|
/* check whether there is any same value node after this node */
|
||||||
|
position = FindNode(currNode->next, currNode->data);
|
||||||
|
|
||||||
|
/* position is not 0, means this is the duplicated value */
|
||||||
|
if (position) {
|
||||||
|
/* record current duplicated value */
|
||||||
|
oldValue = currNode->data;
|
||||||
|
|
||||||
|
/* then use a for loop jump pass the duplicated value,
|
||||||
|
* use for loop to check currNode is not NULL
|
||||||
|
* before get currNode->data */
|
||||||
|
for (; currNode; currNode=currNode->next) {
|
||||||
|
/* exit when we find a new value */
|
||||||
|
if (currNode->data != oldValue) {
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* if this is not a duplicated value,
|
||||||
|
* add unique node to new linked list */
|
||||||
|
InsertNode(&newHead, 0, currNode->data);
|
||||||
|
|
||||||
|
/* move to next */
|
||||||
|
currNode = currNode->next;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Inverst to original direction */
|
||||||
|
InverstNode(&newHead);
|
||||||
|
/* reset head, remember to destory old list, avoid memory leak */
|
||||||
|
DestroyList(*head);
|
||||||
|
*head = newHead;
|
||||||
|
}
|
||||||
58
assignment1/problem1/list.h
Normal file
58
assignment1/problem1/list.h
Normal file
@@ -0,0 +1,58 @@
|
|||||||
|
#ifndef MY_STACK
|
||||||
|
#define MY_STACK
|
||||||
|
|
||||||
|
#include <stdbool.h>
|
||||||
|
|
||||||
|
typedef struct node {
|
||||||
|
double data;
|
||||||
|
struct node *next;
|
||||||
|
} Node;
|
||||||
|
|
||||||
|
/* function: tests whether a list is empty
|
||||||
|
input: head: pointer to the first node
|
||||||
|
output: true if the list is empty and false otherwise
|
||||||
|
*/
|
||||||
|
bool IsEmpty(Node *head);
|
||||||
|
|
||||||
|
/* function: inserts a new node with certain data after a certain position
|
||||||
|
input: phead: pointer to the pointer to the first node
|
||||||
|
index: the new node is inserted after position index
|
||||||
|
insert a new node as the head if index is 0
|
||||||
|
x: data of the new node
|
||||||
|
output: a pointer to the new node if insertion is successful, NULL otherwise
|
||||||
|
*/
|
||||||
|
Node *InsertNode(Node **phead, int index, double x);
|
||||||
|
|
||||||
|
/* function: finds node with certain data
|
||||||
|
input: head: pointer to the first node
|
||||||
|
x: the first node whose data = x is returned
|
||||||
|
output: returns the position of the first node whose data = x
|
||||||
|
returns 0 if no such node exists
|
||||||
|
*/
|
||||||
|
int FindNode(Node *head, double x);
|
||||||
|
|
||||||
|
/* function: deletes a node with certain data
|
||||||
|
input: phead: pointer to the pointer to the first node
|
||||||
|
x: the first node whose data = x is deleted
|
||||||
|
output: returns the position of the deleted node
|
||||||
|
returns 0 if no such node exists
|
||||||
|
*/
|
||||||
|
int DeleteNode(Node **phead, double x);
|
||||||
|
|
||||||
|
/* function: prints all the nodes in the list
|
||||||
|
input: head: pointer to the first node
|
||||||
|
*/
|
||||||
|
void DisplayList(Node *head);
|
||||||
|
|
||||||
|
/* function: deletes all the nodes in the list and frees their memory
|
||||||
|
input: head: pointer to the first node
|
||||||
|
*/
|
||||||
|
void DestroyList(Node *head);
|
||||||
|
|
||||||
|
/* inverse a linked list */
|
||||||
|
void InverstNode(Node **head);
|
||||||
|
|
||||||
|
/* delete all duplicates node in a linked list */
|
||||||
|
void RemoveDuplicates(Node **head);
|
||||||
|
|
||||||
|
#endif
|
||||||
180
assignment1/problem1/test_main.c
Normal file
180
assignment1/problem1/test_main.c
Normal file
@@ -0,0 +1,180 @@
|
|||||||
|
/* author: Walter
|
||||||
|
* Student_ID: 1930006025
|
||||||
|
* Assignment_problem_1
|
||||||
|
* This is a test unit file contain some test function and a main function to run it
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include <stdlib.h>
|
||||||
|
#include <stdio.h>
|
||||||
|
|
||||||
|
#include "list.h"
|
||||||
|
|
||||||
|
void test_inverse_empty_list();
|
||||||
|
void test_inverse_one_list();
|
||||||
|
void test_inverst_list();
|
||||||
|
void test_remove_duplicate();
|
||||||
|
|
||||||
|
int main() {
|
||||||
|
test_inverse_empty_list();
|
||||||
|
test_inverse_one_list();
|
||||||
|
test_inverst_list();
|
||||||
|
test_remove_duplicate();
|
||||||
|
}
|
||||||
|
|
||||||
|
void test_inverse_empty_list() {
|
||||||
|
Node *head = NULL;
|
||||||
|
printf("test_inverse_empty_list(): except 2 empty line:\n");
|
||||||
|
DisplayList(head);
|
||||||
|
InverstNode(&head);
|
||||||
|
DisplayList(head);
|
||||||
|
}
|
||||||
|
|
||||||
|
void test_inverse_one_list() {
|
||||||
|
Node *head = NULL;
|
||||||
|
printf("test_inverse_one_list(): except two same node:\n");
|
||||||
|
InsertNode(&head, 0, 39.0);
|
||||||
|
DisplayList(head);
|
||||||
|
InverstNode(&head);
|
||||||
|
DisplayList(head);
|
||||||
|
DestroyList(head);
|
||||||
|
head = NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
void test_inverst_list() {
|
||||||
|
Node *head = NULL;
|
||||||
|
printf("test_inverst_list(): except inverse list:\n");
|
||||||
|
for (int i=39; i<45; i++) {
|
||||||
|
InsertNode(&head, 0, (double)i);
|
||||||
|
}
|
||||||
|
DisplayList(head);
|
||||||
|
InverstNode(&head);
|
||||||
|
DisplayList(head);
|
||||||
|
DestroyList(head);
|
||||||
|
head = NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* four test cases from pdf */
|
||||||
|
void test_remove_duplicate() {
|
||||||
|
Node *head = NULL;
|
||||||
|
|
||||||
|
printf("test_remove_duplicate(): except 1.0 4.0:\n");
|
||||||
|
InsertNode(&head, 0, 1.0);
|
||||||
|
InsertNode(&head, 1, 2.0);
|
||||||
|
InsertNode(&head, 2, 2.0);
|
||||||
|
InsertNode(&head, 3, 4.0);
|
||||||
|
InsertNode(&head, 4, 6.0);
|
||||||
|
InsertNode(&head, 5, 6.0);
|
||||||
|
DisplayList(head);
|
||||||
|
RemoveDuplicates(&head);
|
||||||
|
DisplayList(head);
|
||||||
|
DestroyList(head);
|
||||||
|
head = NULL;
|
||||||
|
|
||||||
|
printf("test_remove_duplicate(): except two empty line:\n");
|
||||||
|
head = NULL;
|
||||||
|
DisplayList(head);
|
||||||
|
RemoveDuplicates(&head);
|
||||||
|
DisplayList(head);
|
||||||
|
DestroyList(head);
|
||||||
|
head = NULL;
|
||||||
|
|
||||||
|
printf("test_remove_duplicate(): except empty line in result:\n");
|
||||||
|
head = NULL;
|
||||||
|
InsertNode(&head, 0, 6.0);
|
||||||
|
InsertNode(&head, 1, 6.0);
|
||||||
|
InsertNode(&head, 2, 6.0);
|
||||||
|
InsertNode(&head, 3, 7.0);
|
||||||
|
InsertNode(&head, 4, 7.0);
|
||||||
|
DisplayList(head);
|
||||||
|
RemoveDuplicates(&head);
|
||||||
|
DisplayList(head);
|
||||||
|
DestroyList(head);
|
||||||
|
head = NULL;
|
||||||
|
|
||||||
|
printf("test_remove_duplicate(): except 6.0 7.0:\n");
|
||||||
|
head = NULL;
|
||||||
|
InsertNode(&head, 0, 6.0);
|
||||||
|
InsertNode(&head, 1, 7.0);
|
||||||
|
DisplayList(head);
|
||||||
|
RemoveDuplicates(&head);
|
||||||
|
DisplayList(head);
|
||||||
|
DestroyList(head);
|
||||||
|
head = NULL;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/* old test function
|
||||||
|
// Testing all the functions:
|
||||||
|
int main(void) {
|
||||||
|
Node *head = NULL;
|
||||||
|
|
||||||
|
// Output: true
|
||||||
|
printf("%s\n", IsEmpty(head) ? "true" : "false");
|
||||||
|
|
||||||
|
// Must output an empty line:
|
||||||
|
DisplayList(head);
|
||||||
|
|
||||||
|
// Must output "insert failed":
|
||||||
|
Node *result = InsertNode(&head, 20, 7);
|
||||||
|
printf("%s\n", result == NULL ? "insert failed" : "insert succeeded");
|
||||||
|
|
||||||
|
// Output: 0.000000 1.000000 2.000000 3.000000 4.000000
|
||||||
|
for (int i = 0; i < 5; i++) {
|
||||||
|
InsertNode(&head, i, i);
|
||||||
|
}
|
||||||
|
DisplayList(head);
|
||||||
|
|
||||||
|
// Output: false
|
||||||
|
printf("%s\n", IsEmpty(head) ? "true" : "false");
|
||||||
|
|
||||||
|
// Output: 4.000000 3.000000 2.000000 1.000000 0.000000
|
||||||
|
// 0.000000 1.000000 2.000000 3.000000 4.000000
|
||||||
|
for (int i = 0; i < 5; i++) {
|
||||||
|
InsertNode(&head, 0, i);
|
||||||
|
}
|
||||||
|
DisplayList(head);
|
||||||
|
|
||||||
|
// Output: 0.000000 is at position 5
|
||||||
|
// 2.000000 is at position 3
|
||||||
|
// 4.000000 is at position 1
|
||||||
|
// 6.000000 is not in the list
|
||||||
|
for (int i = 0; i < 7; i += 2) {
|
||||||
|
int idx = FindNode(head, i);
|
||||||
|
if (idx > 0) {
|
||||||
|
printf("%f is at position %d\n", (double)i, idx);
|
||||||
|
} else {
|
||||||
|
printf("%f is not in the list\n", (double)i);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Output: inserted 10.000000
|
||||||
|
// 4.000000 3.000000 2.000000 10.000000 1.000000 0.000000
|
||||||
|
// 0.000000 1.000000 2.000000 3.000000 4.000000
|
||||||
|
Node *in = InsertNode(&head, 3, 10);
|
||||||
|
printf("inserted %f\n", in->data);
|
||||||
|
DisplayList(head);
|
||||||
|
|
||||||
|
// Output: 4.000000 3.000000 2.000000 10.000000 1.000000
|
||||||
|
// 0.000000 1.000000 2.000000 3.000000 4.000000
|
||||||
|
// 3.000000 2.000000 10.000000 1.000000
|
||||||
|
// 0.000000 1.000000 2.000000 3.000000 4.000000
|
||||||
|
// 3.000000 2.000000 10.000000 1.000000
|
||||||
|
// 0.000000 1.000000 2.000000 3.000000
|
||||||
|
DeleteNode(&head, 0); // Delete in the middle of the list.
|
||||||
|
DisplayList(head);
|
||||||
|
DeleteNode(&head, 4); // Delete at the front of the list.
|
||||||
|
DisplayList(head);
|
||||||
|
DeleteNode(&head, 4); // Delete at the end of the list.
|
||||||
|
DisplayList(head);
|
||||||
|
|
||||||
|
printf("Reverse List ...\n");
|
||||||
|
InverstNode(&head);
|
||||||
|
DisplayList(head);
|
||||||
|
|
||||||
|
DestroyList(head);
|
||||||
|
head = NULL;
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
*/
|
||||||
Reference in New Issue
Block a user