这个程序主要用到的是C的链表知识。算属于数据结构中的吧,简单的单向链表。我很惭愧阿,还没搞懂二叉树。要是有牛人指点二三,不胜感激阿。废话少说,代码供上,牛人莫笑。

///////////////////////////////////////////////////////////////////////////////////////////////////////////////////
//这是个简单的书本录入程序,实现的是从输入书本名,作者和价钱,保存到一结构体组成的内存空间里。退出时信息会丢失。 //
//功能很简单,但用到了C中很多知识点,主要是学习结构体的使用和链表使用和函数的用法。我花了点时间用中文注释了下,供//
//个人参考 //,程序编译成功运行,有爱好者可下载在UNIX平台编译运行。因水平实在有限,难免错误地方太多,望见谅。大家//
//可以互相学习探讨,我的联系方世如下                                                                                                                                                               
//MSN:[email]wu23qing45ying@163.com[/email]                                                                                                                                                                                //
//QQ: 46499596                                                                                                     //
//E-mail: [email]carywu@yahoo.cn[/email]  / [email]wu23qing45ying@163.com[/email]                                                            //
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////

//////////////////////////////////////////////////
//头文件                                        //
//////////////////////////////////////////////////
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>

#define NAME_SIZE 50
#define MAXBOOKS  30


//////////////////////////////////////////////////
//结构体定义                                    //
//////////////////////////////////////////////////
typedef struct library
{
  char name[NAME_SIZE]; //书名,用的是数组,
  char auther[NAME_SIZE]; //作者名。
  float value; //价格
  int number; //序号

  struct library *next; //链表指针。
} library_t, *point;


//////////////////////////////////////////////////
//结构体定义                                    //
//////////////////////////////////////////////////

void delete_enter (char *s);
void print_list (point current);
void book_append (point head);
void book_delete (point current);
int number = 0; //全局定义序号,初始值为0.


//////////////////////////////////////////////////
//主函数                                        //
//////////////////////////////////////////////////
int
main (int argc, char **argv)
{
  point current = NULL, head = NULL, prev = NULL; //定义当前连表指针,头指针,前一个指针。

  fprintf (stdout, "Please input the book name:\n");

  char temp_storage[NAME_SIZE]; //定义一临时存储书名的数组。因为指针还为分配内存,不能用。

  while (fgets (temp_storage, NAME_SIZE, stdin) != NULL //我用的是fgets,会将回车符存入,所以需要个删除回车做法。
  && temp_storage[0] != '\n')
    {
      delete_enter (temp_storage); //删除回车符的函数,在下面有具体。

      current = (point) malloc (sizeof (library_t)); //分配当前节点的内存,用于存储数据。
      strcpy (current->name, temp_storage); //将临时中的字符串复制到结构题中的name数组中。
      fprintf (stdout, "please input the auther name\n");
      fgets (current->auther, NAME_SIZE, stdin); //同上,输入作者名。有个问题是没做错误检测。
      delete_enter (current->auther); //同上。
      fprintf (stdout, "please input the book value\n");
      scanf ("%f", &current->value); //输入价格。直接用scanf。
      number++; //序号自加。
      current->number += number; //传给结构题中的number,实现每多一链表节点序号增加1。

      if (head == NULL) //当头指针为空时,指向当前节点。
    {
   head = current;
    }
      else  //否则,前指针的下一跳指向当前节点。 这样三个指针都指向了具体的节点。
    {
   prev->next = current;
    }

      current->next = NULL; //当前指针的下一跳设为空。

      fprintf (stdout, "number      name      auther      value\n"); //输出信息。每次输完一个节点信息后,就输出查看。
      fprintf (stdout, "%d    %10s    %10s       %.2f\n", current->number,
        current->name, current->auther, current->value);

      prev = current; //将前指针指向当前节点。


      fprintf (stdout, "Please input the next name:\n");

      while (getchar () != '\n')
    continue;
    }

  fprintf (stdout, "below is the append program\n");
  current = head; //将当前指针指回到头节点,实现链表的遍历。
  book_append (current); //这是个按照序号选择来插入新节点信息的函数。

  fprintf (stdout, "show the total book list\n");
  current = head; //同上。当前指针回归到头节点。
  print_list (current); //这是个打印整个链表信息的函数。

  fprintf(stdout, "below is the delete program\n");
  current = head; //同上。
  book_delete(current); //这是个按照序号选择来删除节点的函数。

  fprintf (stdout, "show the total book list\n");
  current = head;
  print_list (current); //删除后再打印一次。我很苦恼似乎重复使用打印函数。

  return 0;
}

void
delete_enter (char *s) //删除回车空行函数,很简单。
{
  int i;
  while (s[i] != '\n')
    ++i;
  if (s[i] == '\n')
    s[i] = '\0';

}

void
print_list (point current)
{
  fprintf (stdout,
    "number %10s book_name %10s book_auther %10s book_value %10s\n",
    " ", " ", " ", " ");
  while (current != NULL) //在当前指针指向空节点时结束。
    {

      fprintf (stdout, "%d        %s           %10s        %10s  %.2f\n",
        current->number, current->name, current->auther, " ",
        current->value);
      fprintf (stdout, "%20s\n", "--------------");
      current = current->next;
    }
}

void
book_append (point current)
{
  int word_number;
  point new_code = NULL;

  fprintf (stdout, "please input the number you want to add behind\n");
  scanf ("%d", &word_number);
  for (; current != NULL; current = current->next)
    {
      if (word_number == current->number)
    {
   new_code = (point) malloc (sizeof (library_t));

   fprintf (stdout, "please input the book name\n");
   while (getchar () != '\n')
     continue;
   fgets (new_code->name, NAME_SIZE, stdin);
   delete_enter (new_code->name);
   fprintf (stdout, "please input the book auther\n");
   fgets (new_code->auther, NAME_SIZE, stdin);
   delete_enter (new_code->auther);
   fprintf (stdout, "please input the book value\n");
   scanf ("%f", &new_code->value);
   number++;
   new_code->number += number;
   new_code->next = current->next;
   current->next = new_code;

   break;
    }
      else
    continue;
    }
}

void
book_delete (point current) //当前节点被指向了头节点。
{
  int word_number;
  point prev; //定义一个新的辅助前指针。

  fprintf (stdout, "please input the number you want to delete\n");
  scanf ("%d", &word_number); //选择要删除的序号。

  while (current != NULL)
    {
      prev = current; //删除单向链表其实很简单,前指针指向当前节点。
      current = current->next; //当前指针指向下一个节点。
      if (word_number == current->number) //在序号相等情况下。
    {
   prev->next = current->next; //将前节点的下一跳指向当前节点的下一跳节点,也就是把当前节点孤立不链接。
   free (current); //free掉当前节点。
   break; //退出。
    }
      else
    continue; //多此一举,不过写上好看些。
    }
}