C语言链表综合操作

来源:互联网 发布:软件开发项目进度表 编辑:程序博客网 时间:2024/04/30 13:44

/*----------------------------------预处理命令-----------------------------------------*/

#include <stdio.h>

#include <malloc.h>

#define LEN sizeof(struct student)

#define FORMAT "%ld,%f"

#define P_FORMAT "%ld   %5.1f\n"      

#define Null 0

/*---------------------------------构造结构体------------------------------------------*/

struct student//构造一个结构体类型 

{

long num;//学生学号

float score;//学生成绩

struct student *next;//存放下一节点地址的指针变量

};

 

int n = 0;                   //用于统计节点个数的全局变量

 

/*---------------------------------建立链表函数--------------------------------------- */

struct student *creat(void) //建立链表的函数

{

struct student *p1,*p2,*head;   

n = 0;//头结点个数初始化为0

    p2 = p1 = (struct student *)malloc(LEN);//开辟一个节点,并使p1、p2指向它

    scanf(FORMAT,&p1->num,&p1 ->score);//对第一个节点赋值

head = Null;//将头指针初始化为Null    

while (p1->num != 0)

{

n = n + 1; //统计节点个数

if (n == 1)

{

head = p1;//将第一个节点的地址发送给头指针

}

else

{

p2->next = p1;//将新开辟的节点的地址发给前一节点指针变量next

}

        p2 = p1;//将p2指向表尾(当前链表的最后一个节点)

p1 = (struct student *)malloc(LEN);//再开辟一个新节点,使p1指向它

scanf(FORMAT,&p1->num,&p1 ->score);

}

p2->next = Null;//若新开辟的节点num=0,那么表尾节点的指针变量置为NULL

return (head);

}

/*-----------------------------------输出链表函数--------------------------------------- */

void print(struct student *head)//输出链表的函数

{

struct student *p;

printf("\n\nNOW,These %d record are:\n",n);

if (head != Null)     //判断头指针是否为空

{

        p = head;         //使p指第一个节点

do 

{

printf(P_FORMAT,p->num,p->score);//输出p所指的节点的成员

p = p->next;                    //使p指向下一节点

}while (p != Null);

}

else

{

printf(" \nlist Null!\n");

}

return;

}

/*----------------------------------删除链表节点函数----------------------------------- */

struct student *del(struct student *head,long num)//删除链表节点的函数

{

    struct student *p1,*p2;

    

if (head == Null)                //判断头指针是否为空

{

printf("\nlist Null!\n");   

}

    else

{

p1 = head;

while (p1->num != num && p1->next != Null)  //当p1所指节点不是要删除的节点以及不是表尾节点时,继续寻找。

{

p2 = p1;

p1 = p1->next;

}

if (p1->num == num)//判断p1是否是要删除的节点

{

if(p1 == head)//判断p1是否指向头结点

{

head = p1->next;

}

else

{

p2->next = p1->next;

}

printf("\n%ld has been deleted\n",num);

n=n-1;

}

else

{

printf("\n%ld is not foud!\n",num);

}

}

return (head);

}

/*----------------------------------增加链表节点函数----------------------------------- */

struct student *insert(struct student *head,struct student *stu)//插入链表节点的函数

{

struct student *p0,*p1,*p2;

p0 = stu;              //使p0指向要插入的节点

if (head == Null)     //判断链表是否为空

{

head = p0;        //将p0所指的节点作为唯一节点

}

else                        

{

p1 = head;        //使p1指向第一个节点

while (p1->num < p0->num && p1->next != Null)//当p1所指的节点成员num小于要插入的节点num以及p1所指的不是表尾节点,继续寻找

{

p2 = p1;

            p1 = p1->next; 

}

if (p0->num  <= p1->num) //判断是否找到大于等于要插入的节点num的节点

{

if (p1 == head)       //判断p1是否指向头结点

head = p0;       //插到表头之前

p0->next = p1;

}

else

{

p2->next = p0;   //插到表中间

p0->next = p1;

}

}

else                    //插到表尾之后

{

p1->next = p0;

p0->next = Null;

}

}

n = n + 1;

return (head);

}

/*----------------------------------主函数----------------------------------- */

int main(void)

{

struct student *stu,*head;

long del_num;

    

printf("Input record:\n");

head = creat();//不能写成head = creat(void);

 

print(head);

 

printf("\nInput the deleted number:");

scanf("%ld",&del_num);

    while (del_num != 0)

{

head = del(head,del_num);

print(head);

   printf("\nInput the deleted number:");

   scanf("%ld",&del_num);

}

    printf("\nInput the inserted record: ");

stu = (struct student*)malloc(LEN);

scanf(FORMAT,&stu->num, &stu->score);

while (stu->num != 0)

    {

head = insert(head,stu);

print(head);

printf("\nInput the inserted record: ");

stu = (struct student*)malloc(LEN);

scanf(FORMAT,&stu->num, &stu->score);

}

printf("The end\n");

return 0;

}

/*在VC++6.0中的输出结果为:

------------------------------------------

Input record:

10101,90

10102,876

10103,87

10104,100

10105,82

10106,76

10107,92

10108,91

10109,76

10110,82

10111,988

0,0

 

 

NOW,These 11 record are:

10101    90.0

10102   876.0

10103    87.0

10104   100.0

10105    82.0

10106    76.0

10107    92.0

10108    91.0

10109    76.0

10110    82.0

10111   988.0

 

Input the deleted number:10102

 

10102 has been deleted

 

 

NOW,These 10 record are:

10101    90.0

10103    87.0

10104   100.0

10105    82.0

10106    76.0

10107    92.0

10108    91.0

10109    76.0

10110    82.0

10111   988.0

 

Input the deleted number:10104

 

10104 has been deleted

 

 

NOW,These 9 record are:

10101    90.0

10103    87.0

10105    82.0

10106    76.0

10107    92.0

10108    91.0

10109    76.0

10110    82.0

10111   988.0

 

Input the deleted number:10111

 

10111 has been deleted

 

 

NOW,These 8 record are:

10101    90.0

10103    87.0

10105    82.0

10106    76.0

10107    92.0

10108    91.0

10109    76.0

10110    82.0

 

Input the deleted number:0

 

Input the inserted record: 10102,81

 

 

NOW,These 9 record are:

10101    90.0

10102    81.0

10103    87.0

10105    82.0

10106    76.0

10107    92.0

10108    91.0

10109    76.0

10110    82.0

 

Input the inserted record: 10104,93

 

 

NOW,These 10 record are:

10101    90.0

10102    81.0

10103    87.0

10104    93.0

10105    82.0

10106    76.0

10107    92.0

10108    91.0

10109    76.0

10110    82.0

 

Input the inserted record: 0,0

The end

Press any key to continue