1.1递归法
1.2 双向链表
2.1 main.c
2.2 list.h
2.3 list.c
3.1 main.c
3.2 list.h
3.3 list.c
4.1 main.c
4.2 queue.h
4.3 queue.c
/* films2.c -- using a linked list of structures */
#include <stdio.h>
#include <stdlib.h> /* has the malloc prototype */
#include <string.h> /* has the strcpy prototype */
#define TSIZE 45 /* size of array to hold title */
struct film {
char title[TSIZE];
int rating;
struct film * next; /* points to next struct in list */
};
void showlist(struct film *);
int main(void)
{
struct film * head = NULL;
struct film * prev, * current;
char input[TSIZE];
/* Gather and store information */
puts("Enter first movie title:");
while (gets(input) != NULL && input[0] != '\0')
{
current = (struct film *) malloc(sizeof(struct film));
if (head == NULL) /* first structure */
head = current;
else /* subsequent structures */
prev->next = current;
current->next = NULL;
strcpy(current->title, input);
puts("Enter your rating <0-10>:");
scanf("%d", ¤t->rating);
while(getchar() != '\n')
continue;
puts("Enter next movie title (empty line to stop):");
prev = current;
}
/* Show list of movies */
if (head == NULL)
printf("No data entered. ");
else
printf ("Here is the movie list:\n");
current = head;
while (current != NULL)
{
printf("Movie: %s Rating: %d\n",
current->title, current->rating);
current = current->next;
}
/*Show list of movies in reversion*/
if (head == NULL)
printf("No data entered. ");
else
{
printf ("Here is the movie list in reversino:\n");
showlist(head);
}
/* Program done, so free allocated memory */
current = head;
while (current != NULL)
{
free(current);
current = current->next;
}
printf("Bye!\n");
return 0;
}
/*Show list of movies in reversino*/
void showlist(struct film * f)
{
if(f->next!=NULL)
showlist(f->next);
printf("Movie: %s Rating: %d\n",f->title,f->rating);
}
1.2 双向链表
/* films2.c -- using a linked list of structures */
#include <stdio.h>
#include <stdlib.h> /* has the malloc prototype */
#include <string.h> /* has the strcpy prototype */
#define TSIZE 45 /* size of array to hold title */
struct film {
char title[TSIZE];
int rating;
struct film * next; /* points to next struct in list */
struct file * front;
};
int main(void)
{
struct film * head = NULL;
struct film * prev, * current;
prev=NULL;
char input[TSIZE];
/* Gather and store information */
puts("Enter first movie title:");
while (gets(input) != NULL && input[0] != '\0')
{
current = (struct film *) malloc(sizeof(struct film));
if (head == NULL) /* first structure */
{
head = current;
current->front=NULL;
}
else /* subsequent structures */
prev->next = current;
if(prev!=NULL)
current->front=prev;
current->next = NULL;
strcpy(current->title, input);
puts("Enter your rating <0-10>:");
scanf("%d", ¤t->rating);
while(getchar() != '\n')
continue;
puts("Enter next movie title (empty line to stop):");
prev = current;
}
/* Show list of movies */
if (head == NULL)
printf("No data entered. ");
else
printf ("Here is the movie list:\n");
current = head;
while (current != NULL)
{
printf("Movie: %s Rating: %d\n",
current->title, current->rating);
current = current->next;
}
/* Show list of movies in reversion */
if (head == NULL)
printf("No data entered. ");
else
printf ("Here is the movie list:\n");
current = prev;
while (current != NULL)
{
printf("Movie: %s Rating: %d\n",
current->title, current->rating);
current = current->front;
}
/* Program done, so free allocated memory */
current = head;
while (current != NULL)
{
free(current);
current = current->next;
}
printf("Bye!\n");
return 0;
}
2.1 main.c
/* films3.c -- using an ADT-style linked list */
/* compile with list.c */
#include <stdio.h>
#include <stdlib.h> /* prototype for exit() */
#include "list.h" /* defines List, Item */
void showmovies(Item item);
int main(void)
{
List movies;
Item temp;
/* initialize */
InitializeList(&movies);
if (ListIsFull(&movies))
{
fprintf(stderr,"No memory available! Bye!\n");
exit(1);
}
/* gather and store */
puts("Enter first movie title:");
while (gets(temp.title) != NULL && temp.title[0] != '\0')
{
puts("Enter your rating <0-10>:");
scanf("%d", &temp.rating);
while(getchar() != '\n')
continue;
if (AddItem(temp, &movies)==false)
{
fprintf(stderr,"Problem allocating memory\n");
break;
}
if (ListIsFull(&movies))
{
puts("The list is now full.");
break;
}
puts("Enter next movie title (empty line to stop):");
}
/* display */
if (ListIsEmpty(&movies))
printf("No data entered. ");
else
{
printf ("Here is the movie list:\n");
Traverse(&movies, showmovies);
}
printf("You entered %d movies.\n", ListItemCount(&movies));
/* clean up */
EmptyTheList(&movies);
printf("Bye!\n");
return 0;
}
void showmovies(Item item)
{
printf("Movie: %s Rating: %d\n", item.title,
item.rating);
}
2.2 list.h
/* list.h -- header file for a simple list type */
#ifndef LIST_H_
#define LIST_H_
#include <stdbool.h> /* C99 feature */
/* program-specific declarations */
#define TSIZE 45 /* size of array to hold title */
struct film
{
char title[TSIZE];
int rating;
};
/* general type definitions */
typedef struct film Item;
typedef struct node
{
Item item;
struct node * next;
} Node;
typedef struct list
{
Node * head; /* 指向列表头 */
Node * end; /* 指向列表尾 */
} List;
/* function prototypes */
/* operation: initialize a list */
/* preconditions: plist points to a list */
/* postconditions: the list is initialized to empty */
void InitializeList(List * plist);
/* operation: determine if list is empty */
/* plist points to an initialized list */
/* postconditions: function returns True if list is empty */
/* and returns False otherwise */
bool ListIsEmpty(const List *plist);
/* operation: determine if list is full */
/* plist points to an initialized list */
/* postconditions: function returns True if list is full */
/* and returns False otherwise */
bool ListIsFull(const List *plist);
/* operation: determine number of items in list */
/* plist points to an initialized list */
/* postconditions: function returns number of items in list */
unsigned int ListItemCount(const List *plist);
/* operation: add item to end of list */
/* preconditions: item is an item to be added to list */
/* plist points to an initialized list */
/* postconditions: if possible, function adds item to end */
/* of list and returns True; otherwise the */
/* function returns False */
bool AddItem(Item item, List * plist);
/* operation: apply a function to each item in list */
/* plist points to an initialized list */
/* pfun points to a function that takes an */
/* Item argument and has no return value */
/* postcondition: the function pointed to by pfun is */
/* executed once for each item in the list */
void Traverse (const List *plist, void (* pfun)(Item item) );
/* operation: free allocated memory, if any */
/* plist points to an initialized list */
/* postconditions: any memory allocated for the list is freed */
/* and the list is set to empty */
void EmptyTheList(List * plist);
#endif
2.3 list.c
/* list.c -- functions supporting list operations */
#include <stdio.h>
#include <stdlib.h>
#include "list.h"
/* local function prototype */
static void CopyToNode(Item item, Node * pnode);
/* interface functions */
/* set the list to empty */
void InitializeList(List * plist)
{
plist->head= NULL;
plist->end=NULL;
}
/* returns true if list is empty */
bool ListIsEmpty(const List * plist)
{
if (plist->head == NULL)
return true;
else
return false;
}
/* returns true if list is full */
bool ListIsFull(const List * plist)
{
Node * pt;
bool full;
pt = (Node *) malloc(sizeof(Node));
if (pt == NULL)
full = true;
else
full = false;
free(pt);
return full;
}
/* returns number of nodes */
unsigned int ListItemCount(const List * plist)
{
unsigned int count = 0;
Node * pnode = plist->head; /* set to start of list */
while (pnode != NULL)
{
++count;
pnode = pnode->next; /* set to next node */
}
return count;
}
/* creates node to hold item and adds it to the end of */
/* the list pointed to by plist (slow implementation) */
bool AddItem(Item item, List * plist)
{
Node * pnew;
Node * scan = plist->head;
pnew = (Node *) malloc(sizeof(Node));
if (pnew == NULL)
return false; /* quit function on failure */
CopyToNode(item, pnew);
pnew->next = NULL;
if (scan == NULL) /* empty list, so place */
{
plist->head = pnew; /* pnew at head of list */
plist->end = pnew;
}
else
{
plist->end->next = pnew;
plist->end = pnew;
}
return true;
}
/* visit each node and execute function pointed to by pfun */
void Traverse (const List * plist, void (* pfun)(Item item) )
{
Node * pnode = plist->head; /* set to start of list */
while (pnode != NULL)
{
(*pfun)(pnode->item); /* apply function to item */
pnode = pnode->next; /* advance to next item */
}
}
/* free memory allocated by malloc() */
/* set list pointer to NULL */
void EmptyTheList(List * plist)
{
Node * psave;
while (plist->head != NULL)
{
psave = plist->head->next; /* save address of next node */
free(plist->head); /* free current node */
plist->head = psave; /* advance to next node */
}
plist->end = NULL;
}
/* local function definition */
/* copies an item into a node */
static void CopyToNode(Item item, Node * pnode)
{
pnode->item = item; /* structure copy */
}
3.1 main.c
/* films3.c -- using an ADT-style linked list */
/* compile with list.c */
#include <stdio.h>
#include <stdlib.h> /* prototype for exit() */
#include "list.h" /* defines List, Item */
void showmovies(Item item);
int main(void)
{
List movies;
Item temp;
/* initialize */
InitializeList(&movies);
if (ListIsFull(&movies))
{
fprintf(stderr,"No memory available! Bye!\n");
exit(1);
}
/* gather and store */
puts("Enter first movie title:");
while (gets(temp.title) != NULL && temp.title[0] != '\0')
{
puts("Enter your rating <0-10>:");
scanf("%d", &temp.rating);
while(getchar() != '\n')
continue;
if (AddItem(temp, &movies)==false)
{
fprintf(stderr,"Problem allocating memory\n");
break;
}
if (ListIsFull(&movies))
{
puts("The list is now full.");
break;
}
puts("Enter next movie title (empty line to stop):");
}
/* display */
if (ListIsEmpty(&movies))
printf("No data entered. ");
else
{
printf ("Here is the movie list:\n");
Traverse(&movies, showmovies);
}
printf("You entered %d movies.\n", ListItemCount(&movies));
/* clean up */
EmptyTheList(&movies);
printf("Bye!\n");
return 0;
}
void showmovies(Item item)
{
printf("Movie: %s Rating: %d\n", item.title,
item.rating);
}
3.2 list.h
/* list.h -- header file for a simple list type */
#ifndef LIST_H_
#define LIST_H_
#define MAXSIZE 100
#include <stdbool.h> /* C99 feature */
/* program-specific declarations */
#define TSIZE 45 /* size of array to hold title */
struct film
{
char title[TSIZE];
int rating;
};
/* general type definitions */
typedef struct film Item;
typedef struct list
{
Item entries[MAXSIZE];
int items;
} List;
/* function prototypes */
/* operation: initialize a list */
/* preconditions: plist points to a list */
/* postconditions: the list is initialized to empty */
void InitializeList(List * plist);
/* operation: determine if list is empty */
/* plist points to an initialized list */
/* postconditions: function returns True if list is empty */
/* and returns False otherwise */
bool ListIsEmpty(const List *plist);
/* operation: determine if list is full */
/* plist points to an initialized list */
/* postconditions: function returns True if list is full */
/* and returns False otherwise */
bool ListIsFull(const List *plist);
/* operation: determine number of items in list */
/* plist points to an initialized list */
/* postconditions: function returns number of items in list */
unsigned int ListItemCount(const List *plist);
/* operation: add item to end of list */
/* preconditions: item is an item to be added to list */
/* plist points to an initialized list */
/* postconditions: if possible, function adds item to end */
/* of list and returns True; otherwise the */
/* function returns False */
bool AddItem(Item item, List * plist);
/* operation: apply a function to each item in list */
/* plist points to an initialized list */
/* pfun points to a function that takes an */
/* Item argument and has no return value */
/* postcondition: the function pointed to by pfun is */
/* executed once for each item in the list */
void Traverse (const List *plist, void (* pfun)(Item item) );
/* operation: free allocated memory, if any */
/* plist points to an initialized list */
/* postconditions: any memory allocated for the list is freed */
/* and the list is set to empty */
void EmptyTheList(List * plist);
#endif
3.3 list.c
/* list.c -- functions supporting list operations */
#include <stdio.h>
#include <stdlib.h>
#include "list.h"
/* local function prototype */
static void CopyToNode(Item item, Item * pnode);
/* interface functions */
/* set the list to empty */
void InitializeList(List * plist)
{
plist->items=0;
}
/* returns true if list is empty */
bool ListIsEmpty(const List * plist)
{
if (plist->items == 0)
return true;
else
return false;
}
/* returns true if list is full */
bool ListIsFull(const List * plist)
{
if (plist->items == MAXSIZE)
return true;
else
return false;
}
/* returns number of nodes */
unsigned int ListItemCount(const List * plist)
{
return plist->items;
}
/* creates node to hold item and adds it to the end of */
/* the list pointed to by plist (slow implementation) */
bool AddItem(Item item, List * plist)
{
if (ListIsFull(plist))
return false; /* quit function on failure */
CopyToNode(item, &plist->entries[plist->items]);
plist->items++;
return true;
}
/* visit each node and execute function pointed to by pfun */
void Traverse (const List * plist, void (* pfun)(Item item) )
{
int i;
for(i=0;i<plist->items;i++)
(*pfun)(plist->entries[i]);
}
/* free memory allocated by malloc() */
/* set list pointer to NULL */
void EmptyTheList(List * plist)
{
plist->items=0;
}
/* local function definition */
/* copies an item into a node */
static void CopyToNode(Item item, Item * pnode)
{
*pnode = item; /* structure copy */
}
4.1 main.c
/* mall.c -- use the Queue interface */
/* compile with queue.c */
#include <stdio.h>
#include <stdlib.h> /* for rand() and srand() */
#include <time.h> /* for time() */
#include "queue.h" /* change Item typedef */
#define MIN_PER_HR 60.0
bool newcustomer(double x); /* is there a new customer? */
Item customertime(long when); /* set customer parameters */
int main(void)
{
Queue line1,line2;
Item temp; /* new customer data */
int hours; /* hours of simulation */
int perhour; /* average # of arrivals per hour */
long cycle, cyclelimit; /* loop counter, limit */
long turnaways = 0; /* turned away by full queue */
long customers = 0; /* joined the queue */
long served = 0; /* served during the simulation */
long sum_line = 0; /* cumulative line length */
int wait_time1 = 0,wait_time2=0; /* time until Sigmund is free */
double min_per_cust; /* average time between arrivals */
long line_wait1 = 0,line_wait2=0; /* cumulative time in line */
InitializeQueue(&line1);
InitializeQueue(&line2);
srand(time(0)); /* random initializing of rand() */
puts("Case Study: Sigmund Lander's Advice Booth");
puts("Enter the number of simulation hours:");
scanf("%d", &hours);
cyclelimit = MIN_PER_HR * hours;
puts("Enter the average number of customers per hour:");
scanf("%d", &perhour);
min_per_cust = MIN_PER_HR / perhour;
for (cycle = 0; cycle < cyclelimit; cycle++)
{
if (newcustomer(min_per_cust))
{
if (QueueIsFull(&line1)&&QueueIsFull(&line2))
turnaways++;
else
{
customers++;
temp = customertime(cycle);
if(QueueItemCount(&line1)>QueueItemCount(&line2))
EnQueue(temp, &line2);
else
EnQueue(temp,&line1);
}
}
if (wait_time1 <= 0 && !QueueIsEmpty(&line1))
{
DeQueue (&temp, &line1);
wait_time1 = temp.processtime;
line_wait1 += cycle - temp.arrive;
served++;
}
if (wait_time1 > 0)
wait_time1--;
if (wait_time2 <= 0 && !QueueIsEmpty(&line2))
{
DeQueue (&temp, &line2);
wait_time2 = temp.processtime;
line_wait2 += cycle - temp.arrive;
served++;
}
if (wait_time1 > 0)
wait_time1--;
if (wait_time2 > 0)
wait_time2--;
sum_line += QueueItemCount(&line1)+QueueItemCount(&line2);
}
if (customers > 0)
{
printf("customers accepted: %ld\n", customers);
printf(" customers served: %ld\n", served);
printf(" turnaways: %ld\n", turnaways);
printf("average queue size: %.2f\n",
(double) sum_line / cyclelimit/2);
printf(" average wait time: %.2f minutes\n",
(double) (line_wait1+line_wait2) / served/2);
}
else
puts("No customers!");
EmptyTheQueue(&line1);
EmptyTheQueue(&line2);
puts("Bye!");
return 0;
}
/* x = average time, in minutes, between customers */
/* return value is true if customer shows up this minute */
bool newcustomer(double x)
{
if (rand() * x / RAND_MAX < 1)
return true;
else
return false;
}
/* when is the time at which the customer arrives */
/* function returns an Item structure with the arrival time */
/* set to when and the processing time set to a random value */
/* in the range 1 - 3 */
Item customertime(long when)
{
Item cust;
cust.processtime = rand() % 3 + 1;
cust.arrive = when;
return cust;
}
4.2 queue.h
/* queue.h -- interface for a queue */
#ifndef _QUEUE_H_
#define _QUEUE_H_
#include <stdbool.h>
/* INSERT ITEM TYPE HERE */
/* FOR EXAMPLE, */
/* use the following for use_q.c */
/* typedef int Item; */
/* OR typedef struct item {int gumption; int charisma;} Item; */
/* use the following for mall.c */
typedef struct item
{
long arrive; /* the time when a customer joins the queue */
int processtime; /* the number of consultation minutes desired */
} Item;
#define MAXQUEUE 10
typedef struct node
{
Item item;
struct node * next;
} Node;
typedef struct queue
{
Node * front; /* pointer to front of queue */
Node * rear; /* pointer to rear of queue */
int items; /* number of items in queue */
} Queue;
/* operation: initialize the queue */
/* precondition: pq points to a queue */
/* postcondition: queue is initialized to being empty */
void InitializeQueue(Queue * pq);
/* operation: check if queue is full */
/* precondition: pq points to previously initialized queue */
/* postcondition: returns True if queue is full, else False */
bool QueueIsFull(const Queue * pq);
/* operation: check if queue is empty */
/* precondition: pq points to previously initialized queue */
/* postcondition: returns True if queue is empty, else False */
bool QueueIsEmpty(const Queue *pq);
/* operation: determine number of items in queue */
/* precondition: pq points to previously initialized queue */
/* postcondition: returns number of items in queue */
int QueueItemCount(const Queue * pq);
/* operation: add item to rear of queue */
/* precondition: pq points to previously initialized queue */
/* item is to be placed at rear of queue */
/* postcondition: if queue is not empty, item is placed at */
/* rear of queue and function returns */
/* True; otherwise, queue is unchanged and */
/* function returns False */
bool EnQueue(Item item, Queue * pq);
/* operation: remove item from front of queue */
/* precondition: pq points to previously initialized queue */
/* postcondition: if queue is not empty, item at head of */
/* queue is copied to *pitem and deleted from */
/* queue, and function returns True; if the */
/* operation empties the queue, the queue is */
/* reset to empty. If the queue is empty to */
/* begin with, queue is unchanged and the */
/* function returns False */
bool DeQueue(Item *pitem, Queue * pq);
/* operation: empty the queue */
/* precondition: pq points to previously initialized queue */
/* postconditions: the queue is empty */
void EmptyTheQueue(Queue * pq);
#endif
4.3 queue.c
/* queue.c -- the Queue type implementation*/
#include <stdio.h>
#include <stdlib.h>
#include "queue.h"
/* local functions */
static void CopyToNode(Item item, Node * pn);
static void CopyToItem(Node * pn, Item * pi);
void InitializeQueue(Queue * pq)
{
pq->front = pq->rear = NULL;
pq->items = 0;
}
bool QueueIsFull(const Queue * pq)
{
return pq->items == MAXQUEUE;
}
bool QueueIsEmpty(const Queue * pq)
{
return pq->items == 0;
}
int QueueItemCount(const Queue * pq)
{
return pq->items;
}
bool EnQueue(Item item, Queue * pq)
{
Node * pnew;
if (QueueIsFull(pq))
return false;
pnew = (Node *) malloc( sizeof(Node));
if (pnew == NULL)
{
fprintf(stderr,"Unable to allocate memory!\n");
exit(1);
}
CopyToNode(item, pnew);
pnew->next = NULL;
if (QueueIsEmpty(pq))
pq->front = pnew; /* item goes to front */
else
pq->rear->next = pnew; /* link at end of queue */
pq->rear = pnew; /* record location of end */
pq->items++; /* one more item in queue */
return true;
}
bool DeQueue(Item * pitem, Queue * pq)
{
Node * pt;
if (QueueIsEmpty(pq))
return false;
CopyToItem(pq->front, pitem);
pt = pq->front;
pq->front = pq->front->next;
free(pt);
pq->items--;
if (pq->items == 0)
pq->rear = NULL;
return true;
}
/* empty the queue */
void EmptyTheQueue(Queue * pq)
{
Item dummy;
while (!QueueIsEmpty(pq))
DeQueue(&dummy, pq);
}
/* Local functions */
static void CopyToNode(Item item, Node * pn)
{
pn->item = item;
}
static void CopyToItem(Node * pn, Item * pi)
{
*pi = pn->item;
}