单链表的基本操作(创建、删除、插入、遍历)

#include<stdio.h>
#include<stdlib.h>
#define NULL 0
#define LEN 10
struct student {
    long num;
    float score;
    student *next;
};
int n;
typedef struct student stu;
stu *create(){
    /*先定义三个指针,head为头指针,p1最为重要,用于后移;p2保存p1后移前的位置,便于p1后移*/
    stu*head;
    stu *p1,*p2;
    /*n是便于计数;指针需要申请结点内存,此时是p1每申请一个空间便输入一个结点数据,
    先把head指针赋值为空,是为了与计数的结点一致;
    p1申请空间并输入数据后,第一个赋值给头指针head,p2用于保存p1当前数据;
    从第二个指针往后,p1仍旧申请新内存和输入数据,p1并赋给下一个p2的next
    若p1->num==0,即到最后,p2的next为空,返回头指针,方便调用*/
    n=0;
    p1=p2=new stu;
    scanf("%ld %f",&p1->num,&p1->score);
    head=NULL;
    while(p1->num!=0){
        n=n+1;
        if(n==1) head=p1;
        else p2->next=p1;
        p2=p1;
        p1=new student ;
        scanf("%ld %f",&p1->num,&p1->score);
    }
    p2->next=NULL;
    return head;
}
stu*del(stu*head,long num){
    /*头指针为空时,返回空指针
    头指针非空时,
    用p1保存头指针并向后寻找符合的条件,找不到时(末尾为空)和找到时跳出循环,
    p2用于保存后后移前数;
    执行删除时,要删除的是头结点时,把p1->next赋值为头结点;
    非头结点时,把p1->next赋给p2->next,就把p1指向的结点删了,结点数n-1
    */
    stu*p1,*p2;
    if(head==NULL){
        printf("list null\n");
    return head;
    }
    p1=head;
    while(num!=p1->num&&p1->next!=NULL){
        p2=p1;p1=p1->next;
    }


    if(num==p1->num){
        if(p1==head)head=p1->next;
        else p2->next=p1->next;
        free(p1);
        printf("delete:%d\n",num);
        n=n-1;
    }
    else printf("cannot find %d",num);
    return head;
}
stu *insert (stu*head,stu*st){//插入结点
/*至少需要三个指针,p1存储头结点,便于从头遍历,p0储存要插入的节点,p2为便于p1后移且插入,
头结点为空时,就差一个结点
不为空时,利用p1与p2向后遍历,找到大于要插入结点值最小的结点
执行插入 末尾之前的,为头指针,直接赋给头指针,不是头指针,赋给p2->next,再用p1赋给p0->next,与后面的连接;
末尾的,直接赋给p1->next,并把p0->next赋空*/
    stu*p0,*p1,*p2;
    p1=head; p0=st;
    if(head==NULL){
        head=p0;
        p0->next=NULL;
    }
    else {
        while((p0->num>p1->num)&&(p1->next!=NULL)){
            p2=p1;
            p1=p1->next;
        }
            if(p0->num<=p1->num){
                if(head==p1)head=p0;
                else p2->next=p0;
                p0->next=p1;
            }
            else {
                p1->next=p0;
                p0->next=NULL;
            }
        }
                n=n+1;
                return head;
}
void print(stu*head){
    stu*p;
    printf("%d个记录\n",n);
    p=head;
    /*前提是头节点不为空,从头指针开始遍历,直到末尾为空*/
    if(head!=NULL)
    do{
        printf("%ld,%.2f\n",p->num,p->score);
        p=p->next;
    }while(p!=NULL);
}


main(){
    stu*head,*st;
long del_num;
head=create();
print(head);
printf("输入要删的学号");
scanf("%ld",&del_num);
while(del_num!=0){
    head=del(head,del_num);
    print(head);
    scanf("%ld",&del_num);
}
st=(stu*)malloc(sizeof(stu));
 printf("输入要插入的点\n");
scanf("%ld %f",&st->num,&st->score);
while(st->num!=0){
    head=insert(head,st);
    print(head);
    printf("输入要插入的点\n");
    st=(stu*)malloc(sizeof(stu));
    scanf("%ld %f",&st->num,&st->score);
}


}

猜你喜欢

转载自blog.csdn.net/lianghudream/article/details/78943132