C语言 单向链表

1、单向链表的定义

struct student
{
    char name[10];
    float score;
    struct student *next;
};

next作为同类型指针,指向与它所在节点一样的节点。

2、单向链表的基本操作

1)建立链表

int main()
{
    /*定义结构指针,pnew指向新节点,head指向头节点,tail指向尾节点*/
    struct student *pnew, *head, * ptail;
    /*
            动态分配库函数malloc,分配长度为sizeof(struct student)的存储空间,函数返回分配到空间的起始地址,
            指向的类型为强制类型转换后的struct student*.
            malloc的头文件stdlib.h
     */
    pnew = (struct student*) malloc(sizeof(struct student));
    /*
            空链表中建立头节点操作。
     */
    scanf("%s%f",pnew->name,&pnew->score);  head = pnew;    ptail = pnew;
    /*
            向现有链表中添加新节点。
     */
    
    pnew = (struct student*) malloc(sizeof(struct student));
    scanf("%s%f",pnew->name,&pnew->score);
    ptail->next = pnew;
    ptail = pnew;
    /*      将末节点指向下一节点的成员赋值为NULL    */
    ptail->next = NULL;
}
/*定义创建函数create,建立一个有n个节点的单向链表*/

struct student *create(int n)
{
    struct student *pnew, *head, *ptail;
    int i;
    pnew = (struct student*) malloc(sizeof(struct student));
    scanf("%s%f",pnew->name, &pnew->score);
    head = ptail = pnew;
    for (i = 1; i < n; i++)
    {
        pnew = (struct student*) malloc(sizeof(struct student));
        scanf("%s%f",pnew->name, &pnew->score);
        ptail->next = pnew;
        ptail = pnew;
    }
    ptail->next = NULL;
    return head;
}

2)遍历链表

/*定义输出链表节点信息函数print,形参head为链表头指针*/

void print(struct student *head)
{
    struct student *p = head;
    while (p != NULL)
    {
        printf("%s  %.1f\n",p->name, p->score);
        p = p->next;
    }
}

3)在链表中插入节点

/*定义函数insert,在有序链表中插入一个节点,使链表按score成员从大到小排列节点*/

struct student* insert(struct student *head)
{
    struct student *p = head, *pnew, *pold = head;
    pnew = (struct student*) malloc(sizeof(struct student));
    scanf("%s%f",pnew->name,&pnew->score);
    if (pnew->score > head->score)  //当新结点score值大于头结点时,将新结点指向头节点,再作为头节点
    {
        pnew->next = head;
        head = pnew;
    }
    else
    {
        while(p != NULL && pnew->score < p->score)
        {
            pold = p;
            p = p->next;
        }
        
        pold->next = pnew;
        pnew->next = p;
    }
    return head;
}

4)在链表中删除节点

/*定义函数pdelete,在链表中删除所有成员score值大于等于grade值的节点。*/

struct student *pdelete(struct student *head, int grade)
{
    struct student *p,*pold;
    
    p = head;
    while (head != NULL && head->score >= grade)    //当头结点为所删除节点时,将头结点指向下一节点,并释放其空间。
    {
        head = head->next;
        free(p);
        p = head;
    }
    if (head == NULL) return head;
    p = head->next;
    pold = head;        //pold指向刚才已检查过的结点。
    while (p != NULL)
    {
        if(p->score >= grade)
        {
            pold->next = p->next;
            free(p);
            p = pold->next;
        }
        else
        {
            pold = p;
            p = p->next;
        }
    }
    return head;
}

题目1

/*输入n个学生的信息(姓名,成绩),根据成绩数据建立一个链表,使链表中的节点按成绩从高到低连接起来。*/
#include <stdio.h>
#include <stdlib.h>

struct student
{
    char name[10];
    float score;
    struct student *next;
};

struct student* insert(struct student *);
void print(struct student *);

int main()
{
    struct student *head;
    int i, n;
    scanf("%d",&n);
    head = (struct student*) malloc(sizeof(struct student));
    scanf("%s%f",head->name, &head->score);
    head->next = NULL;
    for (i = 1;i < n; i++)
    {
        head = insert(head);
    }
    print(head);
    return 0;
}

题目2

/*输入n个学生的信息(姓名、成绩),输出所有学生的节点信息,删除链表中所有不参加补考同学的节点,最后再输出要补考学生的节点信息*/
#include <stdio.h>
#include <stdlib.h>

struct student
{
    char name[10];
    float score;
    struct student *next;
};

struct student* insert(struct student *);
void print(struct student *);
struct student *create(int );
struct student *pdelete(struct student *, int );

int main()
{
    struct student *head;
    int n;
    scanf("%d",&n);
    head = create(n);
    print(head);
    head = pdelete(head,60);
    print(head);
    return 0;
}

单链表冒泡排序

修改数据,或者 先全部修改,再还原指针(这里用第二种方法)

    pi = head;
    while (pi->next != NULL)
    {
        pj = pi->next;
        while (pj != NULL)
        {
            if (pi->date > pj->date)
            {
                t = *pi;
                *pi = *pj;
                *pj = t;
                t.next = pi->next;
                pi->next = pj->next;
                pj->next = t.next;
            }
            pj = pj->next;
        }
        pi = pi->next;
    }
    
    

猜你喜欢

转载自www.cnblogs.com/liumengyue/p/9932274.html