C Primer Plus(第六版)第十七章 编程练习答案

Posted 水番正文

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了C Primer Plus(第六版)第十七章 编程练习答案相关的知识,希望对你有一定的参考价值。

结束了,这本树,现在就差道复习题的答案确认了,最后一题沉浸式解题,仿佛在做逆向题一样,好了,这就是我的这本书看完了每一页做完了每一题的最后一章。--11.26

CH17 Code answer 1:

FilmA

/* 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 film * prev; 
;

char * s_gets(char * st, int n);

int main(void)

    struct film * head = NULL;
    struct film * prev, * current;
    char input[TSIZE];
    
    /* Gather  and store information*/
    puts("Enter first movie title:");
    while (s_gets(input, TSIZE) != NULL && input[0] != '\\0')
    
        current = (struct film *) malloc(sizeof(struct film));
        
        if (head == NULL)       /* first structure       */
        
        	head = current;			//链表头部 
			current->prev = NULL;	//头部没有上一个链表	
		
        else                    /* subsequent structures */
        
        	prev->next = current;	//前一个链表指向当前链表 
        	current->prev = prev;	//当前链表指向上个链表 
		 
        
        current->next = NULL;		//当前链表的下一个链表待定 
        
        strcpy(current->title, input);							//存储项 
        puts("Enter your rating <0-10>:");
        scanf("%d", &current->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");
    
    printf("Reverse order\\n");
    while (current != NULL)						//逆序打印 
    
        printf("Movie: %s  Rating: %d\\n",
               current->title, current->rating);
        current = current->prev;
    
    printf("\\n");
    printf("Positive order\\n");
    current = head;								//正序打印 
    while (current != NULL)
    
        printf("Movie: %s  Rating: %d\\n",
               current->title, current->rating);
        current = current->next;
    
    
    /* Program done, so free allocated memory */
    current = head;
    while (current != NULL)
    
        free(current);
        current = current->next;
    
    printf("\\nBye!");
    
    return 0;


char * s_gets(char * st, int n)

    char * ret_val;
    char * find;
    
    ret_val = fgets(st, n, stdin);
    if (ret_val)
    
        find = strchr(st, '\\n');   // look for newline
        if (find)                  // if the address is not NULL,
            *find = '\\0';          // place a null character there
        else
            while (getchar() != '\\n')
                continue;          // dispose of rest of line
    
    return ret_val;

FilmB

/* 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 */
;

char * s_gets(char * st, int n);
void Re_Pt(struct film * pf);

int main(void)

    struct film * head = NULL;
    struct film * prev, * current;
    char input[TSIZE];
    
    /* Gather  and store information          */
    puts("Enter first movie title:");
    while (s_gets(input, TSIZE) != 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", &current->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;
    
    
    puts("\\n");
    current = head;
    Re_Pt(current);
    
    /* Program done, so free allocated memory */
    current = head;
    while (current != NULL)
    
        free(current);
        current = current->next;
    
    printf("\\nBye!");
    
    return 0;


char * s_gets(char * st, int n)

    char * ret_val;
    char * find;
    
    ret_val = fgets(st, n, stdin);
    if (ret_val)
    
        find = strchr(st, '\\n');   // look for newline
        if (find)                  // if the address is not NULL,
            *find = '\\0';          // place a null character there
        else
            while (getchar() != '\\n')
                continue;          // dispose of rest of line
    
    return ret_val;


void Re_Pt(struct film * pf)

	if (pf->next != NULL)		//如果下一项链表不为空 就向下递归 
		Re_Pt(pf->next);
	printf("Movie: %s  Rating: %d\\n",
               pf->title, pf->rating);

CH17 Code answer 2:

Flims.c

/* films3.c -- using an ADT-style linked list */
/* compile with list.c                        */
#include <stdio.h>
#include <stdlib.h>    /* prototype for exit() */
#include <string.h> 
#include "list.h"      /* defines List, Item   */
void showmovies(Item item);
char * s_gets(char * st, int n);
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 (s_gets(temp.title, TSIZE) != 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);


char * s_gets(char * st, int n)

    char * ret_val;
    char * find;
    
    ret_val = fgets(st, n, stdin);
    if (ret_val)
    
        find = strchr(st, '\\n');   // look for newline
        if (find)                  // if the address is not NULL,
            *find = '\\0';          // place a null character there
        else
            while (getchar() != '\\n')
                continue;          // dispose of rest of line
    
    return ret_val;

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 */
    else
    
        while (scan->next != NULL)
            scan = scan->next;  /* find end of list    */
        scan->next = pnew;      /* add pnew to end     */
    
    
    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      */
    


/* local function definition  */
/* copies an item into a node */
static void CopyToNode(Item item, Node * pnode)

    pnode->item = item;  /* structure copy */

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

CH17 Code answer 3:

Films.c

/* films3.c -- using an ADT-style linked list */
/* compile with list.c                        */
#include <stdio.h>
#include <stdlib.h>    /* prototype for exit() */
#include <string.h>
#include "list.h"      /* defines List, Item   */

void showmovies(Item item);
char * s_gets(char * st, int n);

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 (s_gets(temp.title, TSIZE) != 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);


char * s_gets(char * st, int n)

    char * ret_val;
    char * find;
    
    ret_val = fgets(st, n, stdin);
    if (ret_val)
    
        find = strchr(st, '\\n');   // look for newline
        if (find)                  // if the address is not NULL,
            *find = '\\0';          // place a null character there
        else
            while (getchar() != '\\n')
                continue;          // dispose of rest of line
    
    return ret_val;

list.c

/* list.c -- functions supporting list operations */
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include "list.h"

/* local function prototype */
static void CopyToNode(Item item, Node * pnode);
static void CopyToItem(Item item, Item * entries, int n);

/* interface functions   */
/* set the list to empty */
void InitializeList(List * plist)

    plist->entries[MAXSIZE] =  0 ;
    plist->items = 0;


/* returns true if list is empty */
bool ListIsEmpty(const List * plist)

    if (plist->items == 0)			//直接借用items当下标 所以为0~99 
        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;    /* set to start of list */
//    
//    while (pnode != NULL)
//    
//        ++count;
//        pnode = pnode->next;  /* set to next node     */
//    
    
    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)

//    Node * pnew;
//    Node * scan = *plist;
    
//    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 = pnew;         /* pnew at head of list */
//    else
//    
//        while (scan->next != NULL)
//            scan = scan->next;  /* find end of list    */
//        scan->next = pnew;      /* add pnew to end     */
//    
	if (plist->items >= MAXSIZE)
		return false;
		
    CopyToItem(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) )

//    Node * pnode = *plist;    /* set to start of list   */
//    
//    while (pnode != NULL)
//    
//        (*pfun)(pnode->item); /* apply function to item */
//        pnode = pnode->next;  /* advance to next 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)

//    Node * psave;
//    
//    while (*plist != NULL)
//    
//        psave = (*plist)->next; /* save address of next node */
//        free(*plist);           /* free current node         */
//        *plist = psave;         /* advance to next node      */
//    

	plist->entries[MAXSIZE] =  0 ;
	plist->items = 0;


/* local function definition  */
/* copies an item into a node */
static void CopyToNode(Item item, Node * pnode)

    pnode->item = item;  /* structure copy */


static void CopyToItem(Item item, Item * entries, int n)

	strcpy(entries[n].title, item.title);
	entries[n].rating = item.rating;

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  */
#define MAXSIZE    100

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

	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

CH17 Code answer 4:

mall.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;
	Queue line2; 
    Item temp1;                // new customer data
    Item temp2;
    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;        // time until Sigmund is free
    int wait_time2 = 0; 
    double min_per_cust;      // average time between arrivals
    long line_wait = 0;       // cumulative time in line 
    
    InitializeQueue(&line1);
    InitializeQueue(&line2);
    srand((unsigned int) 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))	//如果都满了 走的顾客就+1 
            	turnaways++;
            else											//肯定都没满 或者一个满了 
            
                customers++;				
                
                if (QueueIsFull(&line1)) 					//line1满了加line2
				
					temp2 = customertime(cycle);			//创建客户数据 
					EnQueue(temp2, &line2);				
					
                else
                
					temp1 = customertime(cycle);			//创建客户数据 
					EnQueue(temp1, &line1);
				 
            
        
        if (wait_time1 <= 0 && !QueueIsEmpty(&line1))
        
            DeQueue (&temp1, &line1);
            wait_time1 = temp1.processtime;					//设置接下来的咨询时间 
            line_wait += cycle - temp1.arrive;				//计算总的 到来时间-咨询时间之前 
            served++;										//咨询人数加一 
        
        
        if (wait_time2 <= 0 && !QueueIsEmpty(&line2))
        
            DeQueue (&temp2, &line2);
            wait_time2 = temp2.processtime;
            line_wait += cycle - temp2.arrive;
            served++;
        
        
        if (wait_time1 > 0)
            wait_time1--;
            
        if (wait_time2 > 0)
			wait_time2--; 
			
        sum_line += QueueItemCount(&line1);
        sum_line += 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);
        printf(" average wait time: %.2f minutes\\n",
               (double) line_wait / served);
    
    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;

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;

queue.h

/* queue.h -- interface for a queue */
#ifndef _QUEUE_H_
#define _QUEUE_H_
#include <stdbool.h>

// INSERT ITEM TYPE HERE
// FOR EXAMPLE,
//typedef int Item;  // for use_q.c
// OR typedef struct item int gumption; int charisma; Item;
// OR  (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

CH17 Code answer 5:

stack.c

#include <stdio.h>
#include "stack.h"

static void ToBeTrueIndex(int * index);

void InitializeStack(Stack * ps)

	ps->top = 0;
	ps->items[MAXSTACK] =  0 ;


bool FullStack(const Stack * ps)

	return ps->top == MAXSTACK - 1;
 

bool EmptyStack(const Stack * ps)

	return ps->top == 0;


bool Push(Item item, Stack * ps)

	if (FullStack(ps))			//如果栈已满返回错误 
		return false;
		
	ps->items[ps->top] = item;		//放入栈顶 
	ps->top++;						//压栈 
	return true;


bool Pop(Item * pitem, Stack * ps)

	if (FullStack(ps))
		return false;
	
	ToBeTrueIndex(&ps->top);
	*pitem = ps->items[ps->top];	//抬栈 
//	ps->top--;						//调整栈顶 
	
	if (ps->top == 0)				//如果栈全面被抬完就初始化栈 
		InitializeStack(ps);
	
	return true;


static void ToBeTrueIndex(int * index)

	--(*index);		//指向栈顶数据 

stack.h

#ifndef STACK_H_		//注意是if n def!!! 看了半天 

#define STACK_H_
#include <stdbool.h>

#define MAXSTACK 10

typedef char Item;
typedef struct stack

	int top;
	Item items[MAXSTACK];	
Stack; 

/*操作:		初始化栈											*/
/*前提条件:	ps指向一个栈										*/ 
/*后置条件:	该栈初始化为空										*/  
void InitializeStack(Stack * ps);

/*操作:		检查栈是否已满										*/
/*前提条件:	ps指向之前已被初始化的栈							*/ 
/*后置条件:	如果栈已经满,该函数返回true						*/
bool FullStack(const Stack * ps);

/*操作:		检查栈是否为空										*/
/*前提条件:	ps指向之前已被初始化的栈							*/ 
/*后置条件:	如果栈为空,该函数放回ture;否者,返回false			*/
bool EmptyStack(const Stack * ps);

/*操作:		把项压入栈顶										*/
/*前提条件:	ps指向之前已被初始化的栈							*/ 
/*				items是待压入栈顶的项				 				*/ 
/*后置条件:	如果栈不满,把item放在栈顶,该函数返回true;		*/
/*				否则,栈不变,该函数返回false		 				*/
bool Push(Item item, Stack * ps);

/*操作:		从栈顶删除项										*/
/*前提条件:	ps指向之前已被初始化的栈							*/ 
/*后置条件:	如果栈不为空,把item拷贝到*pitem					*/
/*				删除栈顶的item,该函数返回true		 				*/
/*				如果该操作后栈中没有项,则重置该项为空				*/
/*				如果删除操作之前栈为空,栈不变,该函数返回false		*/
bool Pop(Item * pitem, Stack * ps);

#endif

use_s.c

#include <stdio.h>
#include <string.h>
#include "stack.h"

int main(void)

	Item temp[MAXSTACK];
	Stack box;
	int i;
	Item t;			//应该为字符 不应该是指针 
	
	printf("Enter a string, I will give you string of reverse!\\n");
	while (scanf("%s", temp))
	 
		InitializeStack(&box);					//初始化栈 
		
		for ( i = 0; i < strlen(temp); i++ )	//将字符压栈 
			Push(temp[i], &box);
		for ( i = 0; i < strlen(temp); i++)		//将字符弹栈 
		
			Pop(&t, &box);
			printf("%c", t);
		
		
		puts("\\n");
		printf("Enter a string, I will give you string of reverse!(enter ^C to quit)\\n");
	
	printf("Bye!");
	
	return 0;

CH17 Code answer 6:

Binary_Search.c

#include <stdio.h>

#define MAX 1024

int Binary_Search(int *, int, int); 
int Pow(int, int);

int main(void)

	int data[MAX];
	int i;
	
	for ( i = 0; i < MAX; i++)
	
		data[i] = i;
//		printf("%d ", data[i]);
	
	
	printf("%d", Binary_Search(data, MAX, 777));	
	
	return 0;	
 

int Binary_Search(int * target, int n, int key)

	int i;
	int index;
	int min = 0, max = n; 
	int len = 0;
	int answer = 0;
	
	while ( Pow(2, len) < n )		//判断是多少2^n - 1以内
		len++;
	
	index = n / 2;					//到中间的位置 
	for ( i = 0; i < len; i++ )
	
		if ( key < target[index] )
		
			max = index;
			index = (min + index) / 2;
			
		else if( key > target[index] )
		
			min = index;
			index = (index + max) / 2; 
			
		else 
			answer = 1;
	
	
	return answer; 


int Pow(int num, int n)

	int i;
	int pow = 1;
	
	if ( n == 0 )
		return 1;
	for ( i = 0; i < n; i++ )
		pow = pow * num;
	
	return pow;

CH17 Code answer 7:

tree.c

/* tree.c -- tree support functions */
#include <string.h>
#include <stdio.h>
#include <stdlib.h>
#include "tree.h"

/* local data type */
typedef struct pair 
    Trnode * parent;
    Trnode * child;
 Pair;

/* protototypes for local functions */
static Trnode * MakeNode(const Item * pi);
static bool ToLeft(const Item * i1, const Item * i2);
static bool ToRight(const Item * i1, const Item * i2);
static void AddNode (Trnode * new_node, Trnode * root);
static void InOrder(const Trnode * root, void (* pfun)(Item item));
static Pair SeekItem(const Item * pi, const Tree * ptree);
static void DeleteNode(Trnode **ptr);
static void DeleteAllNodes(Trnode * ptr);

/* function definitions */
void InitializeTree(Tree * ptree)

    ptree->root = NULL;
    ptree->size = 0;


bool TreeIsEmpty(const Tree * ptree)

    if (ptree->root == NULL)
        return true;
    else
        return false;


bool TreeIsFull(const Tree * ptree)

    if (ptree->size == MAXITEMS)
        return true;
    else
        return false;


int TreeItemCount(const Tree * ptree)

    return ptree->size;


bool AddItem(const Item * pi, Tree * ptree)

    Trnode * new_node;
    Trnode * like;
    
    if  (TreeIsFull(ptree))
    
        fprintf(stderr,"Tree is full\\n");
        return false;             /* early return           */
    
    if ( ( like = SeekItem(pi, ptree).child ) != NULL)				//找到相同的 
    
//        printf("Attempted to add duplicate item\\n");
//        return false;             /* early return           */
        like->item.frequency++;
        
        return true;                  /* successful return      */
    
    new_node = MakeNode(pi);      /* points to new node     */
    if (new_node == NULL)
    
        fprintf(stderr, "Couldn't create node\\n");
        return false;             /* early return           */
    
    /* succeeded in creating a new node */
    ptree->size++;
    
    if (ptree->root == NULL)      /* case 1: tree is empty  */
        ptree->root = new_node;   /* new node is tree root  */
    else                          /* case 2: not empty      */
        AddNode(new_node,ptree->root); /* add node to tree  */
    
    return true;                  /* successful return      */


int InTree(const Item * pi, const Tree * ptree)

	Trnode * temp;
	
    if ( (temp = SeekItem(pi, ptree).child) == NULL )
    	return 0;
    else
    	return temp->item.frequency;


bool DeleteItem(const Item * pi, Tree * ptree)

    Pair look;
    
    look = SeekItem(pi, ptree);
    if (look.child == NULL)
        return false;
    
    if (look.parent == NULL)      /* delete root item       */
        DeleteNode(&ptree->root);
    else if (look.parent->left == look.child)
        DeleteNode(&look.parent->left);
    else
        DeleteNode(&look.parent->right);
    ptree->size--;
    
    return true;


void Traverse (const Tree * ptree, void (* pfun)(Item item))

    if (ptree != NULL)
        InOrder(ptree->root, pfun);


void DeleteAll(Tree * ptree)

    if (ptree != NULL)
        DeleteAllNodes(ptree->root);
    ptree->root = NULL;
    ptree->size = 0;



/* local functions */
static void InOrder(const Trnode * root, void (* pfun)(Item item))

    if (root != NULL)
    
        InOrder(root->left, pfun);
        (*pfun)(root->item);
        InOrder(root->right, pfun);
    


static void DeleteAllNodes(Trnode * root)

    Trnode * pright;
    
    if (root != NULL)
    
        pright = root->right;
        DeleteAllNodes(root->left);
        free(root);
        DeleteAllNodes(pright);
    


static void AddNode (Trnode * new_node, Trnode * root)

    if (ToLeft(&new_node->item, &root->item))
    
        if (root->left == NULL)      /* empty subtree       */
            root->left = new_node;   /* so add node here    */
        else
            AddNode(new_node, root->left);/* else process subtree*/
    
    else if (ToRight(&new_node->item, &root->item))
    
        if (root->right == NULL)
            root->right = new_node;
        else
            AddNode(new_node, root->right);
    
    else                         /* should be no duplicates */
    
//    if ( !strcmp(new_node->item.word, root->item.word) ) 按理来说执行不到这 
//        root->item.n++;		//相同的单词 次数加一
    


static bool ToLeft(const Item * i1, const Item * i2)

    int comp1;
    
    if ((comp1 = strcmp(i1->word, i2->word)) < 0)		//这改了 
        return true;
    else
        return false;


static bool ToRight(const Item * i1, const Item * i2)

    int comp1;
    
    if ((comp1 = strcmp(i1->word, i2->word)) > 0)		//这也改了 
        return true;
    else
        return false;


static Trnode * MakeNode(const Item * pi)

    Trnode * new_node;
    
    new_node = (Trnode *) malloc(sizeof(Trnode));
    if (new_node != NULL)
    
        new_node->item = *pi;
        new_node->left = NULL;
        new_node->right = NULL;
    
    
    return new_node;


static Pair SeekItem(const Item * pi, const Tree * ptree)

    Pair look;
    look.parent = NULL;
    look.child = ptree->root;
    
    if (look.child == NULL)
        return look;                        /* early return   */
    
    while (look.child != NULL)
    
        if (ToLeft(pi, &(look.child->item)))
        
            look.parent = look.child;
            look.child = look.child->left;
        
        else if (ToRight(pi, &(look.child->item)))
        
            look.parent = look.child;
            look.child = look.child->right;
        
        else       /* must be same if not to left or right    */
            break; /* look.child is address of node with item */
    
    
    return look;                       /* successful return   */


static void DeleteNode(Trnode **ptr)
/* ptr is address of parent member pointing to target node  */

    Trnode * temp;
    
    if ( (*ptr)->left == NULL)
    
        temp = *ptr;
        *ptr = (*ptr)->right;
        free(temp);
    
    else if ( (*ptr)->right == NULL)
    
        temp = *ptr;
        *ptr = (*ptr)->left;
        free(temp);
    
    else    /* deleted node has two children */
    
        /* find where to reattach right subtree */
        for (temp = (*ptr)->left; temp->right != NULL;
             temp = temp->right)
            continue;
        temp->right = (*ptr)->right;
        temp = *ptr;
        *ptr =(*ptr)->left;
        free(temp); 
    

tree.h

/* tree.h -- binary search tree                          */
/*           no duplicate items are allowed in this tree */
#ifndef _TREE_H_
#define _TREE_H_
#include <stdbool.h>

/* redefine Item as appropriate */
#define SLEN 20
typedef struct item		

    char word[SLEN];
    int frequency;
 Item;

#define MAXITEMS 10

typedef struct trnode

    Item item;
    struct trnode * left;  /* pointer to right branch  */
    struct trnode * right; /* pointer to left branch   */
 Trnode;

typedef struct tree

    Trnode * root;         /* pointer to root of tree  */
    int size;              /* number of items in tree  */
 Tree;

/* function prototypes */

/* operation:      initialize a tree to empty          */
/* preconditions:  ptree points to a tree              */
/* postconditions: the tree is initialized to empty    */
void InitializeTree(Tree * ptree);

/* operation:      determine if tree is empty          */
/* preconditions:  ptree points to a tree              */
/* postconditions: function returns true if tree is    */
/*                 empty and returns false otherwise   */
bool TreeIsEmpty(const Tree * ptree);

/* operation:      determine if tree is full           */
/* preconditions:  ptree points to a tree              */
/* postconditions: function returns true if tree is    */
/*                 full and returns false otherwise    */
bool TreeIsFull(const Tree * ptree);

/* operation:      determine number of items in tree   */
/* preconditions:  ptree points to a tree              */
/* postconditions: function returns number of items in */
/*                 tree                                */
int TreeItemCount(const Tree * ptree);

/* operation:      add an item to a tree               */
/* preconditions:  pi is address of item to be added   */
/*                 ptree points to an initialized tree */
/* postconditions: if possible, function adds item to  */
/*                 tree and returns true; otherwise,   */
/*                 the function returns false          */
bool AddItem(const Item * pi, Tree * ptree);

/* operation: find an item in a tree                   */
/* preconditions:  pi points to an item                */
/*                 ptree points to an initialized tree */
/* postconditions: function returns true if item is in */
/*                 tree and returns false otherwise    */
int InTree(const Item * pi, const Tree * ptree);

/* operation:      delete an item from a tree          */
/* preconditions:  pi is address of item to be deleted */
/*                 ptree points to an initialized tree */
/* postconditions: if possible, function deletes item  */
/*                 from tree and returns true;         */
/*                 otherwise the function returns false*/
bool DeleteItem(const Item * pi, Tree * ptree);

/* operation:      apply a function to each item in    */
/*                 the tree                            */
/* preconditions:  ptree points to a tree              */
/*                 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 tree */
void Traverse (const Tree * ptree, void (* pfun)(Item item));

/* operation:      delete everything from a tree       */
/* preconditions:  ptree points to an initialized tree */
/* postconditions: tree is empty                       */
void DeleteAll(Tree * ptree);

#endif

petclub.c

/* petclub.c -- use a binary search tree */
#include <stdio.h>
#include <string.h>
#include <ctype.h>
#include <stdlib.h>
#include "tree.h"

char menu(void);
void addpet(Tree * pt, Item * temp);
void droppet(Tree * pt);
void showpets(const Tree * pt);
void findpet(const Tree * pt);
void printitem(Item item);
void uppercase(char * str);
char * s_gets(char * st, int n);

int main(void)

    Tree pets;		
    char choice;		
    Item temp; 	 
    FILE * fp;
    
    if ( (fp = fopen("words.txt", "r")) == NULL )		//判断是否能打开 
    
    	printf("Can't open words.txt!\\n");
    	exit(EXIT_FAILURE);
	
	
	InitializeTree(&pets);								//初始化树 
	while (fscanf(fp, "%s", temp.word) != EOF)			//读入二叉树 
	
//		printf("%s\\n", temp.word); 						//好像好起来了 
		addpet(&pets, &temp);
	
		
    while ((choice = menu()) != 'q')
    
        switch (choice)
        
            case 'l' :  showpets(&pets);
                break;
            case 'f' :  findpet(&pets);
                break;
            default  :  puts("Switching error");
        
        puts("\\n");
    
    DeleteAll(&pets);
    puts("\\nBye.");
    
    return 0;


char menu(void)

    int ch;
    
    puts("Nerfville Pet Club Membership Program");
    puts("Enter the letter corresponding to your choice:");
    puts("l) show list of pets  f) find pets");
    puts("q) quit");
    while ((ch = getchar()) != EOF)
    
        while (getchar() != '\\n')  /* discard rest of line */
            continue;
        ch = tolower(ch);
        if (strchr("lfq",ch) == NULL)
            puts("Please enter an l, f or q:");
        else
            break;
    
    if (ch == EOF)       /* make EOF cause program to quit */
        ch = 'q';
    
    return ch;


void addpet(Tree * pt, Item * temp)
 
    if (TreeIsFull(pt))
        puts("No room in the club!");
    else
    
        uppercase(temp->word);
        temp->frequency = 1;
        AddItem(temp, pt);
    


void showpets(const Tree * pt)

    if (TreeIsEmpty(pt))
        puts("No entries!");
    else
        Traverse(pt, printitem);


void printitem(Item item)

    printf("Word: %-19s  frequency: %-19d\\n", item.word,
           item.frequency);


void findpet(const Tree * pt)

    Item temp;
    int frequency;
    
    if (TreeIsEmpty(pt))
    
        puts("No entries!");
        return;     /* quit function if tree is empty */
    
    
    puts("Please enter word you wish to find:");
    s_gets(temp.word, SLEN);
    uppercase(temp.word);
    temp.frequency = 0;
    
    printf("%s", temp.word);
    if ( frequency = InTree(&temp, pt))
        printf("is a member %d of frequency.\\n", frequency);
    else
        printf("is not a member.\\n");


void uppercase(char * str)

    while (*str)
    
        *str = toupper(*str);
        str++;
    

char * s_gets(char * st, int n)

    char * ret_val;
    char * find;
    
    ret_val = fgets(st, n, stdin);
    if (ret_val)
    
        find = strchr(st, '\\n');   // look for newline
        if (find)                  // if the address is not NULL,
            *find = '\\0';          // place a null character there
        else
            while (getchar() != '\\n')
                continue;          // dispose of rest of line
    
    return ret_val;

CH17 Code answer 8:

pets.c

/* petclub.c -- use a binary search tree */
#include <stdio.h>
#include <string.h>
#include <ctype.h>
#include "tree.h"

char menu(void);
void addpet(Tree * pt);
void droppet(Tree * pt);
void showpets(const Tree * pt);
void findpet(const Tree * pt);
void printitem(Item item);
void uppercase(char * str);
char * s_gets(char * st, int n);

int main(void)

    Tree pets;
    char choice;
    
    InitializeTree(&pets);
    while ((choice = menu()) != 'q')
    
        switch (choice)
        
            case 'a' :  addpet(&pets);
                break;
            case 'l' :  showpets(&pets);
                break;
            case 'f' :  findpet(&pets);
                break;
            case 'n' :  printf("%d pets in club\\n",
                               TreeItemCount(&pets));
                break;
            case 'd' :  droppet(&pets);
                break;
            default  :  puts("Switching error");
        
        puts("\\n");
    
    DeleteAll(&pets);
    puts("Bye.");
    
    return 0;


char menu(void)

    int ch;
    
    puts("Nerfville Pet Club Membership Program");
    puts("Enter the letter corresponding to your choice:");
    puts("a) add a pet          l) show list of pets");
    puts("n) number of pets     f) find pets");
    puts("d) delete a pet       q) quit");
    while ((ch = getchar()) != EOF)
    
        while (getchar() != '\\n')  /* discard rest of line */
            continue;
        ch = tolower(ch);
        if (strchr("alrfndq",ch) == NULL)
            puts("Please enter an a, l, f, n, d, or q:");
        else
            break;
    
    if (ch == EOF)       /* make EOF cause program to quit */
        ch = 'q';
    
    return ch;


void addpet(Tree * pt)

    Item temp;
    
    if (TreeIsFull(pt))
        puts("No room in the club!");
    else
    
        puts("Please enter name of pet:");
        s_gets(temp.petname,SLEN);
        puts("Please enter pet kind:");
        s_gets(temp.petkind[0],SLEN);
        
        uppercase(temp.petname);
        uppercase(temp.petkind[0]);
        
        AddItem(&temp, pt);
    


void showpets(const Tree * pt)

    if (TreeIsEmpty(pt))
        puts("No entries!");
    else
        Traverse(pt, printitem);


void printitem(Item item)

	int i;
	
    printf("Pet: %-19s  Kind:", item.petname);
    for ( i = 0; i <= item.index; i++ )
    	printf("  %s", item.petkind[i]);
    printf("\\n");


void findpet(const Tree * pt)

    Item temp;
    
    if (TreeIsEmpty(pt))
    
        puts("No entries!");
        return;     /* quit function if tree is empty */
    
    
    puts("Please enter name of pet you wish to find:");
    s_gets(temp.petname, SLEN);
    
    uppercase(temp.petname);
    
    printf("%s ", temp.petname);
    if (InTree(&temp, pt))
    
    	printf("is a member.\\n");
	   	SpecialPet(&temp, pt); 
	
        
    else
        printf("is not a member.\\n");


void droppet(Tree * pt)

    Item temp;
    
    if (TreeIsEmpty(pt))
    
        puts("No entries!");
        return;     /* quit function if tree is empty */
    
    
    puts("Please enter name of pet you wish to delete:");
    s_gets(temp.petname, SLEN);
    
    uppercase(temp.petname);
    
    printf("%s ", temp.petname);
    if (DeleteItem(&temp, pt))
        printf("is dropped from the club.\\n");
    else
        printf("is not a member.\\n");


void uppercase(char * str)

    while (*str)
    
        *str = toupper(*str);
        str++;
    

char * s_gets(char * st, int n)

    char * ret_val;
    char * find;
    
    ret_val = fgets(st, n, stdin);
    if (ret_val)
    
        find = strchr(st, '\\n');   // look for newline
        if (find)                  // if the address is not NULL,
            *find = '\\0';          // place a null character there
        else
            while (getchar() != '\\n')
                continue;          // dispose of rest of line
    
    return ret_val;

tree.c

/* tree.c -- tree support functions */
#include <string.h>
#include <stdio.h>
#include <stdlib.h>
#include "tree.h"

/* local data type */
typedef struct pair 
    Trnode * parent;
    Trnode * child;
 Pair;

/* protototypes for local functions */
static Trnode * MakeNode(const Item * pi);
static bool ToLeft(const Item * i1, const Item * i2);
static bool ToRight(const Item * i1, const Item * i2);
static void AddNode (Trnode * new_node, Trnode * root);
static void InOrder(const Trnode * root, void (* pfun)(Item item));
static Pair SeekItem(const Item * pi, const Tree * ptree);
static void DeleteNode(Trnode **ptr);
static void DeleteAllNodes(Trnode * ptr);
static bool TestSame(const Item * i1, const Item * i2);
static void ToBeTrueIndex(Item * item);

/* function definitions */
void InitializeTree(Tree * ptree)

    ptree->root = NULL;
    ptree->size = 0;


bool TreeIsEmpty(const Tree * ptree)

    if (ptree->root == NULL)
        return true;
    else
        return false;


bool TreeIsFull(const Tree * ptree)

    if (ptree->size == MAXITEMS)
        return true;
    else
        return false;


int TreeItemCount(const Tree * ptree)

    return ptree->size;


bool AddItem(const Item * pi, Tree * ptree)

    Trnode * new_node;
    Trnode * temp; 
    
    if  (TreeIsFull(ptree))
    
        fprintf(stderr,"Tree is full\\n");
        return false;             /* early return           */
    
    
    if ((temp = SeekItem(pi, ptree).child) != NULL)//传回来的可能是名字相同 也可能是名字种类都相同 
    
    	if ( TestSame(pi, &temp->item) && (temp->item.index >= MAXLISTS) )//如果种类也相同 就返回错误 
    	
    		fprintf(stderr, "Attempted to add duplicate item\\n");
        	return false;             /* early return           */
		
		else										//只是名字相同 
		
			ToBeTrueIndex(&temp->item);
			strcpy(temp->item.petkind[temp->item.index], pi->petkind[0]);
	
//			printf("%s:%s\\n", temp->item.petname, temp->item.petkind[0]);
//			printf("%s:%s\\n", temp->item.petname, temp->item.petkind[1]);
			
			return true;
		
    
    
    new_node = MakeNode(pi);      /* points to new node     */
    if (new_node == NULL)
    
        fprintf(stderr, "Couldn't create node\\n");
        return false;             /* early return           */
    
    /* succeeded in creating a new node */
    ptree->size++;
    
    if (ptree->root == NULL)      /* case 1: tree is empty  */
        ptree->root = new_node;   /* new node is tree root  */
    else                          /* case 2: not empty      */
        AddNode(new_node,ptree->root); /* add node to tree  */
    
    return true;                  /* successful return      */


bool InTree(const Item * pi, const Tree * ptree)

    return (SeekItem(pi, ptree).child == NULL) ? false : true;


bool DeleteItem(const Item * pi, Tree * ptree)

    Pair look;
    
    look = SeekItem(pi, ptree);
    if (look.child == NULL)
        return false;
    
    if (look.parent == NULL)      /* delete root item       */
        DeleteNode(&ptree->root);
    else if (look.parent->left == look.child)
        DeleteNode(&look.parent->left);
    else
        DeleteNode(&look.parent->right);
    ptree->size--;
    
    return true;


void Traverse (const Tree * ptree, void (* pfun)(Item item))

    if (ptree != NULL)
        InOrder(ptree->root, pfun);


void DeleteAll(Tree * ptree)

    if (ptree != NULL)
        DeleteAllNodes(ptree->root);
    ptree->root = NULL;
    ptree->size = 0;


//有点纠结这算是接口还是内部函数 但感觉肯定不算内部函数
void SpecialPet(const Item * pi, const Tree * ptree)		 

	Trnode * temp;
	int i;
	
	temp = SeekItem(pi, ptree).child;
	
	printf("Pet: %-19s  Kind:", temp->item.petname);
    for ( i = 0; i <= temp->item.index; i++ )
    	printf("  %s", temp->item.petkind[i]);
    printf("\\n");



/* local functions */
static void InOrder(const Trnode * root, void (* pfun)(Item item))

    if (root != NULL)
    
        InOrder(root->left, pfun);
        (*pfun)(root->item);
        InOrder(root->right, pfun);
    


static void DeleteAllNodes(Trnode * root)

    Trnode * pright;
    
    if (root != NULL)
    
        pright = root->right;
        DeleteAllNodes(root->left);
        free(root);
        DeleteAllNodes(pright);
    


static void AddNode (Trnode * new_node, Trnode * root)

    if (ToLeft(&new_node->item, &root->item))
    
        if (root->left == NULL)      /* empty subtree       */
            root->left = new_node;   /* so add node here    */
        else
            AddNode(new_node, root->left);/* else process subtree*/
    
    else if (ToRight(&new_node->item, &root->item))
    
        if (root->right == NULL)
            root->right = new_node;
        else
            AddNode(new_node, root->right);
    
    else                         /* should be no duplicates */
    
        fprintf(stderr,"location error in AddNode()\\n");
        exit(1);
    


static bool ToLeft(const Item * i1, const Item * i2)

    int comp1;
    
    if ((comp1 = strcmp(i1->petname, i2->petname)) < 0)
        return true;
//    else if (comp1 == 0 &&							//不用比较种类 
//             strcmp(i1->petkind, i2->petkind) < 0 )
//        return true;
    else
        return false;


static bool ToRight(const Item * i1, const Item * i2)

    int comp1;
    
    if ((comp1 = strcmp(i1->petname, i2->petname)) > 0)
        return true;
//    else if (comp1 == 0 &&							//不用比较种类 
//             strcmp(i1->petkind, i2->petkind) > 0 )
//        return true;
    else
        return false;


static Trnode * MakeNode(const Item * pi)

    Trnode * new_node;
    
    new_node = (Trnode *) malloc(sizeof(Trnode));
    if (new_node != NULL)
    
        new_node->item = *pi;
        new_node->left = NULL;
        new_node->right = NULL;
    
    
    new_node->item.index = 0;		//初始化节点的下标为0 
    
    return new_node;


static Pair SeekItem(const Item * pi, const Tree * ptree)

    Pair look;
    look.parent = NULL;
    look.child = ptree->root;
    
    if (look.child == NULL)
        return look;                        /* early return   */
    
    while (look.child != NULL)
    
        if (ToLeft(pi, &(look.child->item)))
        
            look.parent = look.child;
            look.child = look.child->left;
        
        else if (ToRight(pi, &(look.child->item))) 
        
            look.parent = look.child;
            look.child = look.child->right;
        
        else       /* must be same if not to left or right    */
            break; /* look.child is address of node with item */
    
    
    return look;                       /* successful return   */


static void DeleteNode(Trnode **ptr)
/* ptr is address of parent member pointing to target node  */

    Trnode * temp;
    
    if ( (*ptr)->left == NULL)
    
        temp = *ptr;
        *ptr = (*ptr)->right;
        free(temp);
    
    else if ( (*ptr)->right == NULL)
    
        temp = *ptr;
        *ptr = (*ptr)->left;
        free(temp);
    
    else    /* deleted node has two children */
    
        /* find where to reattach right subtree */
        for (temp = (*ptr)->left; temp->right != NULL;
             temp 

以上是关于C Primer Plus(第六版)第十七章 编程练习答案的主要内容,如果未能解决你的问题,请参考以下文章

C Primer Plus(第六版)第十四章 编程练习答案

C Primer Plus(第六版)第十五章 编程练习答案

C Primer Plus(第六版)第十二章 编程练习答案

C Primer Plus(第六版)第十一章 编程练习答案

C Primer Plus(第六版)第十三章 编程练习答案

C Primer Plus(第六版)第十六章 编程练习答案