Commit d13a1132 authored by kjc015's avatar kjc015
Browse files

Lab 11, Complete

parent d6477533
#CFLAGS=-g -Wall -Werror
#CFLAGS=-g -Wno-return-local-addr
CFLAGS=-g -Wall
cc=gcc
all: example ll_equal ll_cycle
example: example.o list.o
ll_equal: ll_equal.o list.o
ll_cycle: ll_cycle.o list.o
clean:
rm -f *.o example ll_equal ll_cycle
Kyle Chrysler Kyle Chrysler
Section 63 Section 63
Exercise 1:
1. The -g flag generates debug information. 1. The -g flag generates debug information.
2. You can use break *line number* to make a breakpoint at a certain line. 2. You can use break *line number* to make a breakpoint at a certain line.
3. You can use next to execute the next line of code after stopping at a breakpoint. 3. You can use next to execute the next line of code after stopping at a breakpoint.
...@@ -9,3 +11,7 @@ Section 63 ...@@ -9,3 +11,7 @@ Section 63
6. To see the value of a variable, you can use print. 6. To see the value of a variable, you can use print.
7. You can use info locals to see a list of all variables in the current function. 7. You can use info locals to see a list of all variables in the current function.
8. Backtrace prints a trace of how a program got to where it is. 8. Backtrace prints a trace of how a program got to where it is.
Exercise 2:
The base case was wrong. You are checking to see if A is null, but you did not check to see if B is null. To fix this, I added an || b == NULL to check if B is null.
#include <stdio.h>
#include <stdlib.h>
#include "list.h"
node* mk_node(int val){
node *x = malloc(sizeof(node));
x->val = val;
x->next = NULL;
return x;
}
/* de allocate all memory for a list.
does not work with cycles! */
void ll_destroy(node* list){
if (list == NULL)
return;
if (list->next != NULL)
ll_destroy(list->next);
free (list);
}
void ll_append(node* list, node* new_node){
//move to the end of the list
while (list->next != NULL){
list = list->next;
}
// and link the new node at the end
list->next = new_node;
}
void ll_print(const node* list){
printf("[");
while(list != NULL){
printf("%d", list->val);
if (list->next != NULL){
printf(", ");
}
list = list->next;
}
printf("]\n");
}
/* FIXME: this function is buggy. */
int ll_equal(const node* a, const node* b) {
/* base case, empty lists are equal */
if (a == NULL || b == NULL)
return a == b;
/* check if the first element is the same, if not we're done! */
if (a->val != b->val)
return 0;
/* recurse if they are the same */
return ll_equal(a->next, b->next);
}
/* TODO: write this function, see lab writeup */
int ll_has_cycle(node *head) {
node* tortoise = mk_node(0);
tortoise = head;
node* hare = mk_node(0);
hare = head;
while (1) {
int i;
for (i = 0; i < 2; i++) {
if (hare == NULL) {
return 0;
}
else {
hare = hare->next;
}
}
tortoise = tortoise->next;
if (tortoise == hare) {
return 1;
}
}
return 1;
}
/*
Define a simple linked list node where each
node holds an integer val and a pointer
to the next node.
the typedef makes "node" equal "struct node"
so you don't have to type struct as often */
typedef struct node {
int val;
struct node* next;
} node;
/* create and return a new node */
node* mk_node(int val);
/* de allocate all memory for a list. */
void ll_destroy(node* list);
/* append a node to a non-empty list */
void ll_append(node* list, node* new_node);
/* print the contents of the list */
void ll_print(const node* list);
/* check if lists are the same, meaning
they contain the same values */
int ll_equal(const node* a, const node* b);
/* returns 1 if there is a cycle (loop)
else returns 0 */
int ll_has_cycle(node *head);
#include <stdio.h>
#include "list.h"
void test_ll_has_cycle(void) {
int i;
/* ---------------- Test 1 ---------------- */
/* a simple list of 4 nodes, no cycles */
node *head = mk_node(0);
for (i=1;i<3;i++)
ll_append(head, mk_node(i));
printf("Checking first list for cycles. There should be none, ll_has_cycle says it has %s cycle\n", ll_has_cycle(head)?"a":"no");
/* ---------------- Test 2 ---------------- */
/* a list where the last element loops to the begining of the list */
head = mk_node(4);
for (i=6;i<10;i++)
ll_append(head, mk_node(i));
node *loop = mk_node(10);
loop->next = head;
ll_append(head, loop);
printf("Checking second list for cycles. There should be a cycle, ll_has_cycle says it has %s cycle\n", ll_has_cycle(head)?"a":"no");
/* ---------------- Test 3 ---------------- */
/* a list where a cycle is created in the middle of the list */
head = mk_node(11);
node* middle = NULL;
for (i=11;i<17;i++){
if (i==14){
middle = mk_node(i);
ll_append(head, middle);
}
else{
ll_append(head, mk_node(i));
}
}
loop = mk_node(17);
loop->next = middle;
ll_append(head, loop);
printf("Checking third list for cycles. There should be a cycle, ll_has_cycle says it has %s cycle\n", ll_has_cycle(head)?"a":"no");
/* ---------------- Test 4 ---------------- */
/* a list with a single node that loops back to itself */
head = mk_node(18);
head->next = head;
printf("Checking fourth list for cycles. There should be a cycle, ll_has_cycle says it has %s cycle\n", ll_has_cycle(head)?"a":"no");
/* ---------------- Test 5 ---------------- */
/* just a plain old list, no cycle */
head = mk_node(19);
for (i=19;i<22;i++)
ll_append(head, mk_node(i));
printf("Checking fifth list for cycles. There should be none, ll_has_cycle says it has %s cycle\n", ll_has_cycle(head)?"a":"no");
/* ---------------- Test 6 ---------------- */
/* the null list */
printf("Checking length-zero list for cycles. There should be none, ll_has_cycle says it has %s cycle\n", ll_has_cycle(NULL)?"a":"no");
}
int main(void) {
test_ll_has_cycle();
return 0;
}
#include <stdio.h>
#include "list.h"
/* The main function exists just to test ll_equal.
There are two tests. The second one will fail with
the given code.
Please find the error ll_equal and fix it!
Do not change this file (ll_equal.c)! */
int main(int argc, char** argv) {
int i;
// store pointers for a bunch of nodes, more than we need in fact.
node *nodes[32] = {};
// create 10 nodes and append them to the first node
for (i=0; i<10; i++) {
// all nodes have the same id, 42
nodes[i] = mk_node(42);
if (i > 0){
// append node i onto the list started by node 0
ll_append(nodes[0], nodes[i]);
}
}
// should print [42, 42, 42, 42, 42, 42, 42, 42, 42, 42]
printf("The list of nodes: ");
ll_print(nodes[0]);
// should return 1 (true)
printf("equal test 1 result = %d\n", ll_equal(nodes[0], nodes[0]));
// should return 0 (false)
// instead, it causes a Segmentation fault.
printf("equal test 2 result = %d\n", ll_equal(nodes[0], nodes[2]));
return 0;
}
Supports Markdown
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment