[数据结构] 单向链表

来源:互联网 发布:时时彩源码2017 编辑:程序博客网 时间:2024/04/28 17:35
数据结构之单项链表学习笔记
#include <stdio.h>#include <stdlib.h>struct link *AppendNode(struct link *head,FILE *fp);struct link *DeleteNode(struct link *head, int nodeData);struct link *InsertNode(struct link *head, int nodeData);struct link *ReverseNode(struct link *head);void CountNode(struct link* head);void DeleteAll(struct link *head);void SearchNode(struct link *head, int nodeData);void DisplsyNode(struct link* head);void DeleteMemory(struct link* head);struct link{int data;struct link *next;};

因为方便及作业要求采用int型数据类型,数据采用文件读入链表,先在主函数里将升序数组读入文件,此处可加以修改,读者可自行考虑修改。
int main(){int i = 0;int j;    struct link* head = NULL; /* linked table head pointer*/ FILE *fp;char filename[30];//文件名 int judge; int nodeData;int str[3]={2,3,4};if((fp=fopen("linked table.txt","w"))==NULL)//判断文件是否成功打开 {     printf("Failure to open linked table.txt!\n") ;     exit(0);}     for(i=0;i<2;i++)    {    fprintf(fp,"%d\n",str[i]);    }    fprintf(fp,"%d",str[i]);fclose(fp);//向文件中输入数据 printf("********************Linked Table*********************\n");printf("1.Create\n2.Delete\n3.Insert\n4.Search\n5.Display\n6.Delete All\n7.Count\n8.Reverse\n9.Free\n10.Exit\n"); printf("********************Linked Table*********************\n");scanf("%d",&judge);while(judge!=1&&judge!=10){printf("Have not created a linked table!\n");scanf("%d",&judge);}if(judge==10)   exit(0);printf("Please Input the filename:\n");getchar();//读走回车 gets(filename);if((fp=fopen(filename,"r"))==NULL)//判断文件是否成功打开 {     printf("Failure to open linked table.txt!\n") ;     exit(0);}     for(j=0;!feof(fp);j++)//从文件中将数据读取到链表     {    head = AppendNode(head,fp);    } fclose(fp);printf("Create Successful!\n");DisplsyNode(head);//显示printf("********************Linked Table*********************\n");while(1){    scanf("%d",&judge);    while(judge==1)    {    printf("Repetitive Operation!");    scanf("%d",&judge);    }    if(judge==10)      exit(0);    if(judge==2)    {    printf("Delete nodeData:\n");    scanf("%d",&nodeData);    head = DeleteNode(head,nodeData);    DisplsyNode(head);//显示    printf("********************Linked Table*********************\n");    }        if(judge==3)    {    printf("Insert nodeData:\n");    scanf("%d",&nodeData);    head = InsertNode(head,nodeData);    DisplsyNode(head);//显示    printf("********************Linked Table*********************\n");    }    if(judge==4)    {    printf("Search nodeData:\n");    scanf("%d",&nodeData);    SearchNode(head,nodeData);        printf("********************Linked Table*********************\n");    }        if(judge==5)          DisplsyNode(head);//显示        if(judge==6){DeleteAll(head);//DisplsyNode(head);//显示exit(0);}          if(judge==7)        {        CountNode(head);        printf("********************Linked Table*********************\n");        }    if(judge==8)    {    head=ReverseNode(head);    DisplsyNode(head);//显示    }    if(judge==9){DeleteMemory(head);exit(0);} }DeleteMemory(head);return 0;}
此处由界面判断具体操作注意文件名由键盘输入时会多一个\n,应由getchar()读走。
/*Set a new node and append it to the end of the linked tablereturn the head pointer of the new linked table.*/struct link* AppendNode(struct link *head,FILE *fp){struct link *p=NULL, *pr =head;int data;p = (struct link*)malloc(sizeof(struct link));/*让p指向新节点*/if(p == NULL)//若为新建节点申请内存失败,则退出程序 {printf("No enough memory to allocate! \n");exit(0);} if(head == NULL)//若原链表为空表 {head = p;//将新建节点置为头节点 }else{while (pr->next!=NULL)//若未到表尾,则移动pr直到pr指向表尾{   pr = pr->next;}pr->next = p;/*让末节点的指针域指向新建节点*/ }//printf("Input node data:");fscanf(fp,"%d",&data);p->data = data;p->next = NULL;return head;//return head pointer. }
链表的创建函数,由文件读入
/*for display*/void DisplsyNode(struct link* head){struct link *p = head;int j = 1;while (p != NULL){printf("%5d%10d\n",j,p->data);//打印第J个点的数据p = p->next;j++; }}
链表的显示函数。注意j从1开始计。
void DeleteMemory(struct link *head)//释放内存 {struct link *p=head, *pr = NULL;while(p!=NULL)//若不是表尾,则释放节点占用的内存{    pr = p;p = p->next;free(pr);}}
链表的内存释放函数。
struct link *DeleteNode(struct link *head, int nodeData){struct link *p = head, *pr = head;if(head == NULL)//若链表为空表,则退出程序 {printf("Linked Table is empty!\n");return(head);}while(nodeData != p->data && p->next != NULL)//Not been found and no getting to the end;{pr = p;p=p->next;}if(nodeData == p->data) //若当前节点的节点值为nodeData,找到待删除节点{    if(p == head)//若待删除节点为头节点 {    head = p->next;} else{pr->next = p->next;//important:让前一节点的指针域指向待删节点的下一节点 }free(p); }else{printf("This Node has not been found!\n");}return head;}
链表的删除指定的节点数据。
struct link *InsertNode(struct link *head, int nodeData){struct link *pr = head, *p = head, *temp = NULL;p = (struct link*)malloc(sizeof(struct link));//让p指向待插入节点if(p == NULL){printf("No enough memory!\n");exit(0);//退出程序 } p->next=NULL;//为待插入节点的指针域赋值为空指针p->data=nodeData;//为待插入节点数据域赋值为nodeData if(head == NULL)//若原链表为空表{head = p;} else{while(pr->data < nodeData && pr->next != NULL){temp = pr;pr = pr->next;}if(pr->data >= nodeData){if(pr == head)//若在头节点前加入新节点{     p->next = head;     head = p;}else{pr = temp;p->next = pr->next;pr->next = p;//让前一节点的指针域指向新节点 }}else//表尾 {pr->next = p;//让末节点的指针域指向新节点 } }return head;//return head pointer after inserting the new node of linked table. }
链表之插入指定数据函数,原链表以升序排序,此处给定数据进行比较以确定插入位置。
void SearchNode(struct link *head, int nodeData){struct link *p = head, *pr = head;int i=1;if(head == NULL)//若链表为空表,则退出程序 {printf("Linked Table is empty!\n");}while(nodeData != p->data && p->next != NULL)//Not been found and no getting to the end;{pr = p;p=p->next;i++;}if(nodeData == p->data) //若当前节点的节点值为nodeData{printf("%5d%10d\n",i,p->data);}}
查找指定数据在链表中的位置。
void DeleteAll(struct link *head){struct link *p=head,*pr;if(head == NULL)//若链表为空表,则退出程序 {printf("Linked Table is empty!\n");}while(head!=NULL){            head = p->next;pr = p->next;free(p);            p=pr;                }    printf("Delete All!\n");   }
删除整个链表,删除后头节点为空,显示出现垃圾数据,此处不予显示,待改进疑问
void CountNode(struct link* head){struct link *p = head;int j = 0;while (p != NULL){//printf("%5d%10d\n",j,p->data);//打印第J个点的数据p = p->next;j++; }printf("The Totai nodes are %d.\n",j);}
计算链表长度,遍历链表,与显示函数差不多,直接拷贝。
struct link *ReverseNode(struct link *head){struct link *p1 = head, *p2 = head->next, *p3;if(head==NULL||head->next==NULL)      {          return head;      }while(p2!=NULL){p3 = p2->next;          p2->next = p1;          p1 = p2;          p2 = p3;  }head->next = NULL;      return p1;     }<span style="font-size:14px;"></span>
反序输出链表,注意此处用三个指针进行轮换。
不足之处请诸君指教!!!


0 0