c语言-链表习题

1.尾插法 Q6544

涉及:
(1)创建链表

struct stu* createList() {
    struct stu *head = NULL, *tail = NULL, *newNode;
    char choice;
    char name[20];
    float price;
    do {
        printf("请输入书名 价格:\n");
        scanf("%s %f", name, &price);
        newNode = (struct stu*)malloc(sizeof(struct stu));
        if (newNode == NULL) {
            printf("内存分配失败\n");
            return NULL;
        }
        strcpy(newNode->name, name);
        newNode->price = price;
        newNode->next = NULL;
        if (head == NULL) {
            head = newNode;
            tail = newNode;
        } else {
            tail->next = newNode;
            tail = newNode;
        }
        printf("是否继续输入,按Y键继续输入,其他键就结束.\n");
        scanf(" %c", &choice);
    } while (choice == 'Y' || choice == 'y');
    return head;
}

往链表里一个个添加节点同理,需要注意如果是在主函数中定义的LinkList,且创建链表函数不返回结点指针的话(为void),需要传头结点的地址(尽量不用,用createList返回指针是更容易实现的。),如Q6502

int main()
{
    int choice;
    struct stu *head=NULL,*tail=NULL;
    do{
        printf("1  增加数据\n");
        printf("2  退出\n");
        printf("选择:");
        scanf("%d",&choice);
        if(choice==1){
            Append(&head,&tail);
        }
    }while(choice!=2);
    DisLink(head);
    DeleteMemory(head);
    return 0;
}
void Append(struct stu **head,struct stu **tail){
    struct stu* newNode;
    newNode=(struct stu*)malloc(sizeof(struct stu));
    if(newNode==NULL){
        printf("内存分配失败\n");
        return;
    }
    printf("请输入学号:");
    scanf("%s",newNode->ID);
    printf("请输入名字:");
    scanf("%s",newNode->name);
    printf("请依次输入语文,数学,外语成绩:");
    scanf("%d %d %d",&newNode->c1,&newNode->c2,&newNode->c3);
    newNode->next=NULL;
    if((*head)==NULL){
        (*head)=newNode;
        (*tail)=newNode;
    }
    else{
        (*tail)->next=newNode;
        (*tail)=newNode;
    }
}

(2)查找最大值

void printMostExpensive(struct stu *head) {
    if (head == NULL) {
        return;
    }
    struct stu *max = head;
    struct stu *current = head->next;
    while (current!= NULL) {
        if (current->price > max->price) {
            max = current;
        }
        current = current->next;
    }
    printf("result:\n");
    printf("%s %.2f\n", max->name, max->price);
}

(3)释放内存

void freeList(struct stu *head) {
    struct stu *temp;
    while (head!= NULL) {
        temp = head;
        head = head->next;
        free(temp);
    }
}

在这里插入图片描述
全部代码:

#include <stdio.h>
#include <stdlib.h>
#include <string.h>

// 定义结构体
struct stu {
    char name[20];
    float price;
    struct stu *next;
};

// 创建链表函数
struct stu* createList() {
    struct stu *head = NULL, *tail = NULL, *newNode;
    char choice;
    char name[20];
    float price;
    do {
        printf("请输入书名 价格:\n");
        scanf("%s %f", name, &price);
        newNode = (struct stu*)malloc(sizeof(struct stu));
        if (newNode == NULL) {
            printf("内存分配失败\n");
            return NULL;
        }
        strcpy(newNode->name, name);
        newNode->price = price;
        newNode->next = NULL;
        if (head == NULL) {
            head = newNode;
            tail = newNode;
        } else {
            tail->next = newNode;
            tail = newNode;
        }
        printf("是否继续输入,按Y键继续输入,其他键就结束.\n");
        scanf(" %c", &choice);
    } while (choice == 'Y' || choice == 'y');
    return head;
}

// 输出最贵书籍信息函数
void printMostExpensive(struct stu *head) {
    if (head == NULL) {
        return;
    }
    struct stu *max = head;
    struct stu *current = head->next;
    while (current!= NULL) {
        if (current->price > max->price) {
            max = current;
        }
        current = current->next;
    }
    printf("result:\n");
    printf("%s %.2f\n", max->name, max->price);
}

// 释放链表内存函数
void freeList(struct stu *head) {
    struct stu *temp;
    while (head!= NULL) {
        temp = head;
        head = head->next;
        free(temp);
    }
}

int main() {
    struct stu *head = createList();
    printMostExpensive(head);
    freeList(head);
    return 0;
}
/*
Algorithms 105
Y
高等数学 31.5
Y
C语言 35
J

*/

2.排序 test3

在这里插入图片描述

(1)利用选择排序的方法,降序排序

void descLinkList(Student* head){
    Student *i,*j;
    int tempID;
    char tempName[10];
    float tempScore;
    for(i=head;i!=NULL;i=i->pNextNode){
        for(j=i->pNextNode;j!=NULL;j=j->pNextNode){
            if(i->score<j->score){
                tempID=i->ID;
                i->ID=j->ID;
                j->ID=tempID;
                strcpy(tempName,i->name);
                strcpy(i->name,j->name);
                strcpy(j->name,tempName);
                tempScore=i->score;
                i->score=j->score;
                j->score=tempScore;
            }
        }
    }
}

3.头插法 Q6815

建立带头结点的两个链表哦

void reverse_print(struct ListNode *head){
    struct ListNode *head2=(struct ListNode *)malloc(sizeof(struct ListNode));//链表2的头结点
    head2->next=NULL;
    struct ListNode *p;
    while(head->next!=NULL){
        p=head->next;
        head->next=head->next->next;
        p->next=head2->next;
        head2->next=p;
    }
    head->next=head2->next;
    free(head2);
    
    while(head->next!=NULL){//print
        printf("%d\n",head->next->val);
        head->next=head->next->next;
    }
}

4.遍历链表不许破坏链表结构

错误代码:head->next=head->next->next;破坏了链表结构,导致后续无法再使用该链表。

void show(struct goods *head){
    printf("head2 address is %p\n",head);
    printf("输出所有商品信息为:编号 类型 名称 数量:\n");
    while(head->next!=NULL){
        printf("%d %s %s %d\n",head->next->num,head->next->type,head->next->name,head->next->counts);
        head->next=head->next->next;
    }
}

正确代码:

void show(struct goods *head){
    printf("输出所有商品信息为:编号 类型 名称 数量:\n");
    struct goods *p=head->next;
    while(p!=NULL){
        printf("%d %s %s %d\n",p->num,p->type,p->name,p->counts);
        p=p->next;
    }
}

5.创建循环链表处理问题 Q6816

#include <stdio.h>
#include <stdlib.h>

struct node {
    int data;
    struct node *next;
};

struct node* createList(int n);
void printM(struct node *head,int m);

int main()
{
    int n,m;
    scanf("%d %d",&n,&m);
    struct node *head;
    head=createList(n);//创建循环链表
    printM(head,m);
    return 0;
}
struct node* createList(int n){
    struct node *head=NULL,*tail=NULL,*newNode;
    int i=1;
    for(i=1;i<=n;i++){
        newNode=(struct node*)malloc(sizeof(struct node));
        newNode->data=i;
        newNode->next=NULL;
        if(head==NULL){
            head=newNode;
            tail=head;
        }
        else{
            tail->next=newNode;
            tail=newNode;
        }
    }
    tail->next=head;
    return head;
}
void printM(struct node *head,int m){
    struct node *pre=NULL,*p=head;
    while(p->next!=head){
        p=p->next;
    }
    pre=p;
    p=head;
    int sum=0;
    while(pre!=p){
        sum++;
        if(sum%m==0){
            printf("%d ",p->data);
            pre->next=p->next;
            free(p);
            p=pre->next;
            sum=0;
        }
        else{
            pre=p;
            p=p->next;
        }
    }
    printf("%d",p->data);
    free(p);
}

6.输入到txt再从txt中读出来 Q6510

void outputTxt(struct student *head){
    struct student *p=head->next;
    FILE *fp=fopen("stu.txt","w");
    if(fp==NULL){
        printf("fail to open file!\n");
        return;
    }
    fprintf(fp,"id   name  score\n");
    while(p!=NULL){
        fprintf(fp,"%d     %s   %d\n",p->id,p->name,p->score);
        p=p->next;
    }
    fclose(fp);
    fp=fopen("stu.txt","r");
    int ch;
    while((ch=fgetc(fp))!=EOF){
        putchar(ch);
    }
    fclose(fp);
}
### C语言链表习题 #### 反转单链表 对于反转单链表的问题,可以采用迭代的方法实现。通过三个指针变量 `prev`、`current` 和 `next` 来逐步翻转链表中的每一个节点指向的方向[^1]。 ```c struct ListNode { int val; struct ListNode *next; }; struct ListNode* reverseList(struct ListNode *head) { struct ListNode *prev = NULL, *current = head, *next; while (current != NULL) { next = current->next; // 记录下一个节点 current->next = prev; // 当前节点指向前一个节点 prev = current; // 移动到下一位置 current = next; } return prev; } ``` 此代码片段展示了如何利用三个辅助指针完成链表的反转工作。该算法的时间复杂度为 O(n),其中 n 是链表中节点的数量。 #### 创建并统计单链表 另一个常见的练习是创建一个由用户输入构成的单链表,并计算其长度。这可以通过动态分配内存给新节点并将它们链接在一起的方式完成[^3]。 ```c #include <stdio.h> #include <stdlib.h> typedef struct Node { int data; struct Node *next; } Node; Node* createLinkedList(int size) { if (size <= 0) return NULL; Node *head = NULL, *tail = NULL; for (int i = 0; i < size; ++i) { Node *new_node = (Node *)malloc(sizeof(Node)); printf("Enter element %d: ", i); scanf("%d", &(new_node->data)); new_node->next = NULL; if (!head) { // 如果列表为空,则初始化头部和尾部 head = tail = new_node; } else { // 否则追加到现有列表后面 tail->next = new_node; tail = new_node; } } return head; } void countNodes(Node *list) { int count = 0; while(list){ list = list->next; count++; } printf("Number of nodes in the linked list is :%d\n",count); } ``` 这段代码实现了从标准输入读取一系列整数值来构建单向链表的功能,并提供了一个函数用于打印链表中元素数量的信息。 #### 单链表的操作与特性 当涉及到带有头尾指针的单链表时,某些特定操作可能依赖于链表的实际大小。例如,在删除最后一个元素或者访问最后几个元素的情况下,这些动作通常需要遍历整个链表才能找到目标位置,因此时间开销会随着链表的增长而增加[^4]。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值