C语言复习03(小甲鱼版本)

单链表

int main(void){
   
    struct Test{
   
        int x;
        int y;
        //错误写法:struct Test test;
        struct Test *test;//正确写法,指针指向结构体
    }
}

链表是一种常见的数据结构,根据需求,我们可以构造出单链表、双链表、循环链表和块状链表等。链表的出现很大程度上弥补了数组的先天不足。

[head]———>>[[信息域(存放信息)] [指针(指向链表的下一个元素)]]———>>[[信息域] [指针]]———>>[[信息域] [指针]]———>>[NULL]

//头插法

#include <stdlib.h>
//建立节点
struct Book{
   
    char title[128];
    char author[40];
    struct Book *next;
};

void getInput(struct Book *book){
   
    printf("请输入书名:");
    scanf("%s", book->title);
    printf("请输入作者:");
    scanf("%s", book->author);
}

//在单链表中插入元素
//形参字面上的意思:(*library)是头节点指针library进行一层解引用,然后对其指向的内容(地址)再进行一次解引用
void addBook(struct Book **library) {
   
    struct Book *book, *temp;
    
    //新建一个新的节点
    book = (struct Book *)malloc(sizeof(struct Book));
    
    if (book == NULL){
   
        printf("内存分配失败了\n");
        exit(1);
    }
    
    //填充内容
    getInput(book);
    
    if (*library != NULL){
   
        temp = *library;
        *library = book;
        book->next = temp;
    }
    else{
   
        *library = book;
        book->next = NULL;
    }
}

void printLibrary(struct Book *library){
   
    struct Book *book;
    int count = 1;
    
    book = library;
    while (book != NULL){
   
        printf("Book%d:", count);
        printf("书名:%s:", book->title);
        printf("作者:%s:", book_>author);
        book = book->next;
        count++;
    }
}

void releaseLibrary(struct Book **library){
   
    struct book *temp;
    
    while (*library != NULL){
   
        temp = *library; 
        *library = (*library) -> next;
        free(temp);
    }
}
int main(void){
   
    //library作为头节点指针进行解引用,得到其存放的值,即下一个节点的地址指针
    struct Book *library = NULL;
    
    while(1){
   
        printf("请问是否需要录入书籍信息(Y/N):");
        do{
   
            ch = getchar();
        }while (ch != 'Y' && ch != 'N');
        
        if (ch == 'Y'){
   
            addBook(&library);
        }
        else{
   
            break;
        }
    }
    
    while(1){
   
        printf("请问是否需要打印书籍信息(Y/N):");
        do{
   
            ch = getchar();
        }while (ch != 'Y' && ch != 'N');
        
        if (ch == 'Y'){
   
            printLibrary(library);
        }
        
        releaseLibrary(&library);
        
    }
    
    return 0;
}

观察打印顺序

//尾插法

#include <stdlib.h>
//建立节点
struct Book{
   
    char title[128];
    char author[40];
    struct Book *next;
};

void getInput(struct Book *book){
   
    printf("请输入书名:");
    scanf("%s", book->title);
    printf("请输入作者:");
    scanf("%s", book->author);
}

//在单链表中插入元素
//形参字面上的意思:(*library)是头节点指针library进行一层解引用,然后对其指向的内容(地址)再进行一次解引用
void addBook(struct Book **library) {
   
    struct Book *book, *temp;
    
    //新建一个新的节点
    book = (struct Book *)malloc(sizeof(struct Book));
    
    if (book == NULL){
   
        printf("内存分配失败了\n");
        exit(1);
    }
    
    //填充内容
    getInput(book);
    
    if (*library != NULL){
   
        temp = *library;
        //定位单链表的尾部位置
        while (temp->next != NULL){
   
            temp = temp->next;
        }
        //插入数据
        temp->next = book;
        book->next = NULL;
    }
    else{
   
        *library = book;
        book->next = NULL;
    }
}

void printLibrary(struct Book *library){
   
    struct Book *book;
    int count = 1;
    
    book = library;
    while (book != NULL){
   
        printf("Book%d:", count);
        printf("书名:%s:", book->title);
        printf("作者:%s:", book_>author);
        book = book->next;
        count++;
    }
}

void releaseLibrary(struct Book **library){
   
    struct book *temp;
    
    while (*library != NULL){
   
        temp = *library; 
        *library = (*library) -> next;
        free(temp);
    }
}
int main(void){
   
    //library作为头节点指针进行解引用,得到其存放的值,即下一个节点的地址指针
    struct Book *library = NULL;
    
    while(1){
   
        printf("请问是否需要录入书籍信息(Y/N):");
        do{
   
            ch = getchar();
        }while (ch != 'Y' && ch != 'N');
        
        if (ch == 'Y'){
   
            addBook(&library);
        }
        else{
   
            break;
        }
    }
    
    while(1){
   
        printf("请问是否需要打印书籍信息(Y/N):");
        do{
   
            ch = getchar();
        }while (ch != 'Y' && ch != 'N');
        
        if (ch == 'Y'){
   
            printLibrary(library);
        }
        
        releaseLibrary(&library);
        
    }
    
    return 0;
}

上述尾插法每次插入新元素都需要遍历一次链表,耗时多,是否可以记录下尾节点的地址呢

void addBook(struct Book **library){
   
    struct Book *book;
    //为防止每次进入函数,tail都会被初始化,我们将其变成静态变量:直到程序退出才释放,不然永久保存上一次的值
    static struct Book *tail;
    
     book = (struct Book *)malloc(sizeof(struct Book));
    
    if (book == NULL){
   </
  • 1
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值