C链表(转)

//============================================================================================
//程序名称: 链表操作
//功能描述: 写若干函数,可以实现创建链表,删除,增加,查找,打印等功能
//组成文件: main.c stdio.h stdlib.h
//子函数 : LIST *creat(void);      void prtlist(LIST*);
//     void search(LIST*);      void emptylist(LIST*);
//     LIST *applynode(void);     LIST * addnode(LIST * hds, LIST *pinsert);
//     LIST * deletenode(LIST * hds); void list_wr_file(LIST *hds);
//     void display(void);     void FucSel(void);
//     void list_rd_file(void);    unsigned int list_node_count(const LIST *hds)
//============================================================================================
#include <stdio.h>
#include <stdlib.h>
//定义的结点
typedef struct stu
{
int num;
int age;
struct stu *next;
}LIST;
//函数原型
LIST *creat(void);                              //创建函数
void prtlist(LIST *);                    //打印函数
void search(LIST *);                   //搜索函数
void emptylist(LIST *hds);                 //释放链表
LIST * applynode(void);                        //申请结点
LIST * addnode(LIST * hds, LIST *pinsert); //增加结点
LIST * deletenode(LIST * hds);                  //删除结点
unsigned int list_node_count(LIST *hds);        //结点统计
void list_wr_file(LIST *hds);                   //写入文件
void list_rd_file(void);       //从文件读
void sort_list(LIST *hds);       //链表排序
void display(void);                           //菜单显示
void FucSel(void);                             //功能选择

//系统退出标志
char Flag;

/*
*主函数
*/
int main(void)
{
while(1)
{
   display();          //菜单显示
   FucSel();           //功能选择
   if(Flag)             //退出系统
    break;
}
return 0;
}

/*
*创建链表
*/
LIST *creat()
{
LIST *head = NULL;
LIST *prev, *current;
char index;
int node;

printf("Do you want to create how many nodes?\n");
printf("Please input node's number: ");
while(1 != scanf("%d", &node))
   getchar();                                   //创建node的个数

for(index = 0; index < node; index++)                
{
   current = (LIST *)malloc(sizeof(LIST));      //分配新的node地址
   if(head == NULL)
    head = current;                          //空表建立的时候
   else
    prev->next = current;                    //非空表
   current->next = NULL;
   scanf("%d %d", &current->num, &current->age);
   prev = current;                              //更新老node的地址
}
return head;
}

/*
*打印函数
*/
void prtlist(LIST *hds)
{
char index = 0;

printf(" the list's all infor as following: \n");
if(hds == NULL)                                  //链表为空提示信息
   printf(" Oh,my god!this is empty list\n");
while(hds != NULL)                               //从head开始打印
{
   index++;
   printf(" the NO.%d : num is %d age is %d\n", index, hds->num, hds->age);
   hds = hds->next;
}
printf("\n");
}

/*
*查找函数
*/
void search(LIST *hds)
{
    int innum;
   
    printf(" Do you want to search?");
    printf(" Please input your num : ");
    scanf("%d", &innum);                         //输入要查找的num
   
    if(hds == NULL)
    printf(" the list is empty\n");          //空表查询时候提示信息
while(hds != NULL)
{
   if(hds->num == innum)                    //从head开始寻找目标num
   {
    printf(" the search result: the num is %d, the age is %d \n", hds->num, hds->age);
    break;
   }
   hds = hds->next;
}
printf("\n");
}

/*
*申请结点
*/
LIST * applynode(void)
{
LIST *newnode = (LIST *)malloc(sizeof(LIST));

printf(" please input the newnode's infor: ");
scanf("%d %d", &newnode->num, &newnode->age);
return newnode;
}

/*
*增加结点
*/

//pf为当前的指针,pb为下一个node的指针
LIST *addnode(LIST * hds,LIST *pinsert)
{
LIST *pf,*pb;
pb = hds;  
if(hds == NULL)              //判断head是否为空    
{
   hds = pinsert;
   pinsert->next = NULL;     //空表直接加
}

else       
{
   while( (pinsert->num > pb->num) && (pb->next!=NULL) )
   {
    pf = pb;      
    pb = pb->next;                //根据num号选择位置
   }       
   if(pinsert->num <= pb->num)       //while循环不成立2个原因,要么插入的num <=,要么就是到尾结点了
   {
    if(hds == pb)
    {
     hds = pinsert;
     pinsert->next = pb;     //如果插在head的后面  
    }
    else
    {
     pf->next = pinsert;  
     pinsert->next = pb;     //如果插在中间
    }
   }
   else
   {
    pb->next = pinsert;         //如果插在最后
    pinsert->next = NULL;
   }        
}
return hds;                         //返回更新后的head
}  


/*
*删除接点
*/
LIST * deletenode(LIST * hds)
{
LIST *pf, *pb;
int num;
printf(" please input you want to delete num: ");
scanf("%d",&num);

if(hds == NULL)     //如为空表, 输出提示信息
{
   printf("\n empty list!\n");
   goto end;    
}
pb = hds;

//不为空则载入列表
while (pb->num != num && pb->next != NULL)   //当不是要删除的结点,而且也不是最后一个结点时,继续循环           
{
   pf=pb;
   pb=pb->next;        //pf指向当前结点,pb指向下一结点
}

//pb所指向的就是要删除的
if (pb->num == num)
{
   if(pb == hds)
    hds = pb->next;    //如找到被删结点,且为第一结点,则使head指向第二个结点,
   else
    pf->next=pb->next;      //删除中间结点和最后结点程序一致
   
   free(pb);         //释放删除节点所占空间
    printf(" The node is deleted\n");
}
else
   printf(" The node not been foud!\n");
end:
   return hds;
}


/*
*菜单界面
*/

void display(void)
{
printf("    |**************MENU**************|\n");
printf(" 1->|*******   creat a list   *******|\n");
printf(" 2->|******    display a list ******|\n");
printf(" 3->|*****     search a list    *****|\n");
printf(" 4->|****      add a node        ****|\n");
printf(" 5->|***       delete a node      ***|\n");
printf(" 6->|***       how many nodes?    ***|\n");
printf(" 7->|****      write to file     ****|\n");
printf(" 8->|*****     read from file   *****|\n");
printf(" 9->|******    sort a list     ******|\n");
printf("10->|*******   Quit the sys   *******|\n");
}

/*
*功能选择
*/
void FucSel(void)
{
   int choice;
   static LIST *heds = NULL;      //初始为空,可以判断是否为空表
static LIST *insertp;

//输入的内容必须为1-10
printf("\n please input your choice 1-10 : ");
while((1 != scanf("%d",&choice)) || (choice<1 || choice>10))
   printf(" plese input your choice IN 1、2...10: ");
printf("\n");
   switch(choice)
{
   case 1:
    heds = creat();
    break;
   case 2:
    prtlist(heds);
    break;
   case 3:
    search(heds);
    break;
   case 4:
    insertp = applynode();
    heds = addnode(heds,insertp);
    break;
   case 5:
    heds = deletenode(heds);
    break;
   case 6:
    printf(" the nodes' num are %u\n", list_node_count(heds));
    break;
   case 7:
    list_wr_file(heds);
    break;
   case 8:
    list_rd_file();
    break;
   case 9:
    sort_list(heds);
    prtlist(heds);
    break;
   case 10:
    emptylist(heds);
    Flag = 1;
    break;
   default:
    break;
   }
}


/*
*释放链表
*/
void emptylist(LIST *hds)
{
   LIST *tmp;
  
   tmp = hds;
   while(tmp != NULL)
   {
    free(tmp);
    tmp = tmp->next;
   }
   printf(" **********BYE BYE!!!*********\n");
}

/*
*链表写入文件
*/
int nodecount = 0;
void list_wr_file(LIST *hds)
{
   FILE *fp;
   LIST *head;
  
   if((fp = fopen("list.bin", "w+")) == NULL)          //打开文件
   {
    printf(" Error in openning file\n");
    exit(1);
   }
   head = hds;
   while(head != NULL)                                 //node写入
   {
    fwrite(head, sizeof(LIST), 1, fp);
    head = head->next;
    nodecount++;
   }
   if(fclose(fp) != 0)
   {
    printf(" Error in closing file\n");
    exit(2);
   }
   if(hds == NULL)                                    //空链表写入提示
    printf(" WARNING : LIST IS EMPTY...\n");
   else
    printf(" Success in writing list to file...\n");
}

/*
*从文件读入链表
*/
void list_rd_file(void)
{
FILE *fp;
LIST *save = (LIST *)malloc(sizeof(LIST)*nodecount);
LIST *tsave = save;
char index;


if((fp = fopen("list.bin", "r")) == NULL)              //打开文件
   {
    printf(" Error in openning file\n");
    exit(1);
   }
   if(getc(fp) == EOF)                                    //判断读入的文件是否为空
   {
    printf(" This is a empty file\n");
    goto end;
   }
   rewind(fp);                                            //不为空,则从文件头开始读取
   for(index = 0; index < nodecount; index++)             //读入内容
   {
    fread(save, sizeof(LIST), 1, fp);
    save++;
   }
  
   printf("the info from file: \n");
   for(index = 0; index < nodecount; index++)             //打印内容
   {
    printf("From File the NO.%d:the num is %d; the age is %d.\n", index+1, tsave->num, tsave->age);
    tsave++;
   }
   nodecount = 0;                                         //读完后,将结点数置为0, 以便下次读取
                  //新的nodecount,nodecount为外部的
   end:
   if(fclose(fp) != 0)                                    //关闭文件
   {
    printf(" Error in closing file\n");
    exit(2);
   }
}

/*
*NODE统计
*/
unsigned int list_node_count( LIST *hds)
{
LIST *head = hds;
unsigned int count = 0;

while(head != NULL)
{
   ++count;
   head = head->next;
}
return count;
}

/*
*链表排序
*/
void sort_list(LIST *hds)
{
LIST *pb, *pc;                                                   
unsigned int ncount;                            //node的个数
char in_index, out_index;

ncount = list_node_count(hds);                  //算出当前排序链表node的个数
pb = hds;                                       //内外循环排序,不改变结构,只改变结构体内数据
pc = hds->next;

if(hds == NULL)                                                     //空表不需要排序
{
   printf(" This is a EMPTY list,NO SORTING!\n");
   goto end;
}               
if(hds->next == NULL)                                               //一个node的表不需排序
{
   printf(" The List Only One Data: the num is %d, the age is %d",\
     hds->num, hds->age);
   goto end;
}
//链表不为空,也至少存在2个node
for(out_index = 0; out_index < ncount-1; out_index++)
{
   for(in_index = out_index+1; in_index < ncount; in_index++)
   {
   
    if(pb->num > pc->num)
    {
     int tmp_num;
     tmp_num = pb->num;
     pb->num = pc->num;
     pc->num = tmp_num;
    }
    pc = pc->next;
   }
   pb = pb->next;
   pc = pb->next;
}
end:
;
}

posted @ 2010-03-09 19:58  thunderhao  阅读(122)  评论(0编辑  收藏  举报