C语言基础(三十三)

1、链表排序之归并排序与线性搜索

测试代码:

cpp 复制代码
#include "date.h" 
#include <stdio.h>
#include <stdlib.h>

// 链表节点结构体
typedef struct Node {
    int data;
    struct Node *next;
} Node;

// 插入节点到链表末尾
Node* insertNode(Node *head, int data) {
    Node *newNode = (Node*)malloc(sizeof(Node));
    newNode->data = data;
    newNode->next = NULL;

    if (head == NULL) {
        head = newNode;
    } else {
        Node *current = head;
        while (current->next != NULL) {
            current = current->next;
        }
        current->next = newNode;
    }

    return head;
}

// 归并排序
Node* merge(Node *head) {
    if (head == NULL || head->next == NULL) {
        return head;
    }

    // 分割链表
    Node *slow = head, *fast = head->next;
    while (fast != NULL && fast->next != NULL) {
        slow = slow->next;
        fast = fast->next->next;
    }

    Node *head2 = slow->next;
    slow->next = NULL;

    // 合并排序
    head = merge(head);
    head2 = merge(head2);

    Node dummy;
    Node *ptr = &dummy;
    while (head != NULL && head2 != NULL) {
        if (head->data < head2->data) {
            ptr->next = head;
            head = head->next;
        } else {
            ptr->next = head2;
            head2 = head2->next;
        }
        ptr = ptr->next;
    }

    ptr->next = (head != NULL) ? head : head2;

    return dummy.next;
}

// 遍历链表
void printList(Node *head) {
    Node *current = head;
    while (current != NULL) {
        printf("Data: %d, Address: %p\n", current->data, (void*)current);
        current = current->next;
    }
}

// 线性搜索
int linearSearch(Node *head, int target, Node **foundNodes) {
    int count = 0;
    Node *current = head;
    while (current != NULL) {
        if (current->data == target) {
            foundNodes[count] = current;
            count++;
        }
        current = current->next;
    }
    return count;
}

int main() {
	int times = getTime();
    int n;
    printf("Enter the number of random numbers: ");
    scanf("%d", &n);

    Node *head = NULL;
    for (int i = 0; i < n; i++) {
        int randomNumber = rand() % 100; // 生成0-99范围内的随机数
        head = insertNode(head, randomNumber);
    }

    printf("Before sorting:\n");
    printList(head);

    head = merge(head);

    printf("After sorting:\n");
    printList(head);

    int target;
    printf("Enter the element to search for: ");
    scanf("%d", &target);

    Node *foundNodes[n];
    int count = linearSearch(head, target, foundNodes);

    if (count > 0) {
        printf("Found %d elements:\n", count);
        for (int i = 0; i < count; i++) {
            printf("Data: %d, Address: %p\n", foundNodes[i]->data, (void*)foundNodes[i]);
        }
    } else {
        printf("Element not found.\n");
    }

    return 0;
}

运行结果如下:

2、 链表排序之插入排序与二分搜索:

测试代码:

cpp 复制代码
#include "date.h" 
#include <stdio.h>
#include <stdlib.h>

typedef struct Node {
    int data;
    struct Node* next;
} Node;

// 插入排序
void insertSort(Node** head) {
    if (*head == NULL || (*head)->next == NULL) {
        return;
    }
    
    Node* sorted = NULL;
    Node* current = *head;
    
    while (current != NULL) {
        Node* next = current->next;
        
        if (sorted == NULL || current->data < sorted->data) {
            current->next = sorted;
            sorted = current;
        } else {
            Node* temp = sorted;
            while (temp->next != NULL && temp->next->data < current->data) {
                temp = temp->next;
            }
            current->next = temp->next;
            temp->next = current;
        }
        
        current = next;
    }
    *head = sorted;
}

// 输出链表
void printList(Node* head) {
    Node* current = head;
    while (current != NULL) {
        printf("Data: %d, Address: %p\n", current->data, (void*)current);
        current = current->next;
    }
}

// 二分搜索
Node* binarySearch(Node* head, int target) {
    Node* left = head;
    Node* right = NULL;
    
    // 获取链表结尾
    for (Node* curr = head; curr != NULL; curr = curr->next) {
        right = curr;
    }
    
    while (left != right) {
        Node* mid = left;
        
        int len = 0;
        while (mid != right) {
            len++;
            mid = mid->next;
        }
        len /= 2;
        
        mid = left;
        for (int i = 0; i < len; i++) {
            mid = mid->next;
        }
        
        if (mid->data == target) {
            return mid;
        } else if (mid->data < target) {
            left = mid->next;
        } else {
            right = mid;
        }
    }
    return NULL;
}

int main() {
	int times = getTime();
    int n;
    printf("Enter the number of elements: ");
    scanf("%d", &n);
    
    Node* head = NULL;
    
    // 生成随机数并添加到链表
    for (int i = 0; i < n; i++) {
        Node* newNode = (Node*)malloc(sizeof(Node));
        newNode->data = rand();
        newNode->next = head;
        head = newNode;
    }
    
    printf("Unsorted List:\n");
    printList(head);
    
    // 对链表进行插入排序
    insertSort(&head);
    
    printf("\nSorted List:\n");
    printList(head);
    
    // 二分搜索指定的元素
    int target;
    printf("\nEnter the element to search: ");
    scanf("%d", &target);
    
    Node* result = binarySearch(head, target);
    if (result != NULL) {
        printf("Element found - Data: %d, Address: %p\n", result->data, (void*)result);
    } else {
        printf("Element not found\n");
    }
    
    return 0;
}

运行结果如下;

相关推荐
KpLn_HJL37 分钟前
leetcode - 2139. Minimum Moves to Reach Target Score
java·数据结构·leetcode
Schwertlilien39 分钟前
图像处理-Ch5-图像复原与重建
c语言·开发语言·机器学习
程序员buddha2 小时前
C语言从入门到放弃教程
c语言·开发语言
程序员老冯头2 小时前
第十五章 C++ 数组
开发语言·c++·算法
AAA.建材批发刘哥6 小时前
Linux快速入门-Linux文件系统管理
linux·运维·服务器·c语言·学习方法
AC使者6 小时前
5820 丰富的周日生活
数据结构·算法
cwj&xyp7 小时前
Python(二)str、list、tuple、dict、set
前端·python·算法
无 证明7 小时前
new 分配空间;引用
数据结构·c++
Kisorge7 小时前
【C语言】指针数组、数组指针、函数指针、指针函数、函数指针数组、回调函数
c语言·开发语言
xiaoshiguang311 小时前
LeetCode:222.完全二叉树节点的数量
算法·leetcode