首页 > 其他分享 >c语言实现:链表创建、插入、删除、翻转

c语言实现:链表创建、插入、删除、翻转

时间:2024-09-29 21:23:01浏览次数:3  
标签:Node head main next 链表 插入 NULL data 翻转

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

// 链表创建
typedef struct Node{
    int data;
    struct Node* next;
} Node;

// 创建一个节点
Node* createNode(int data){
    Node* newNode = (Node* )malloc(sizeof(Node));
    newNode->data = data;
    newNode->next = NULL;
    return newNode;
}

// 创建并插入一个节点
void insertNode(Node* head, int data){ // 要修改head得传入地址
    Node* insert = createNode(data);
    insert->next = head->next;
    head->next = insert;
}

// 打印链表
void nodeListPrint(Node* head){
    int index = 0;
    head = head->next;
    while(head != NULL){
        printf("index: %d, head->data: %d\n", index, head->data);
        head = head->next;
        index ++;
    }
}

// 根据data的值获取节点
Node* getNodeByData(Node* head, int data){
    while(head != NULL){
        if(head->data == data) return head;
        head = head->next;
    }
    printf("no wish node: %d\n", data);
    return NULL;
}


// 根据data的值删除节点
void deleteNodeByData(Node* head, int data){
    Node* delete = getNodeByData(head, data);
    if(delete == NULL) return;
    while(head != NULL && head->next != delete) head = head->next;
    head->next = delete->next;
    delete->next = NULL;
    free(delete);
}

// 链表翻转
void nodeListReverse(Node** head){
    Node* nodehead = *head; 
    Node* oldhead = (*head)->next;
    Node* next = NULL;
    *head = NULL;
    
    while(oldhead != NULL){
        next = oldhead->next;
        oldhead->next = *head;
        *head = oldhead;
        oldhead = next;
    }

    nodehead->next = *head;
    *head = nodehead;
}

int main(){
    
    Node* head = (Node* )malloc(sizeof(Node)); // 创建头节点
    for(int i = 1; i <= 10; i ++) insertNode(head, i);
    printf("1.完整链表如下:\n");
    nodeListPrint(head);
    printf("2.删除后的链表如下:\n");
    deleteNodeByData(head, 2);
    deleteNodeByData(head, 6);
    nodeListPrint(head);
    printf("3.链表翻转如下:\n");
    nodeListReverse(&head);
    nodeListPrint(head);
    printf("4.删除后的链表如下:\n");
    deleteNodeByData(head, 7);
    deleteNodeByData(head, 8);
    nodeListPrint(head);
    return 0;
    
}

在这里插入图片描述

其中链表翻转也可以不用二阶指针,但是需要做返还在主函数要接收

// 链表翻转一阶指针
Node* nodeListReverse1(Node* head){
    Node* nodehead = head;
    Node* nhead = NULL;
    Node* next = NULL;
    head = head->next;

    while(head != NULL){
        next = head->next;
        head->next = nhead;
        nhead = head;
        head = next;
    }
    nodehead->next = nhead;
    nhead = nodehead;
    return nhead;
}

在这里插入图片描述
在这里插入图片描述
结果仍然是一样的

void insertNodeEnd(Node* head, int data){
    Node* insert = createNode(data);
    while(head->next != NULL) head = head->next;
    head->next = insert;
    insert->next = NULL;
}

除了链表头插法还有尾插法

在这里插入图片描述

其他补充:

Makefile可以这样写:

runm: clean MAIN
	./MAIN

MAIN: main.o
	gcc -o MAIN main.o

main.o: main.c
	gcc -c main.c -o main.o

clean:
	rm -f *.o MAIN TEST

runt: clean TEST
	./TEST

TEST: test.o
	gcc -o TEST test.o

test.o: test.c
	gcc -c test.c -o test.o

优化后如下所示:

TRV1 = MAIN
TRV2 = TEST
TEP1 = main.o
TEP2 = test.o
ORG1 = main.c
ORG2 = test.c


runm: clean $(TRV1)
	./$(TRV1)

$(TRV1): $(TEP1)
	gcc -o $@ $<

$(TEP1): $(ORG1)
	gcc -c $< -o $@

clean:
	rm -f *.o MAIN TEST

runt: clean $(TRV2)
	./$(TRV2)

$(TRV2): $(TEP2)
	gcc -o $@ $<

$(TEP2): $(ORG2)
	gcc -c $< -o $@

标签:Node,head,main,next,链表,插入,NULL,data,翻转
From: https://blog.csdn.net/xyint/article/details/142528195

相关文章

  • 代码随想录算法训练营第四天|24. 两两交换链表中的节点,19.删除链表的倒数第N个节点,面
    24.两两交换链表中的节点文章链接:https://programmercarl.com/0024.两两交换链表中的节点.html#思路视频讲解:https://www.bilibili.com/video/BV1YT411g7br代码链接:https://leetcode.cn/problems/swap-nodes-in-pairs/此题注意点:注意由于交换节点,head已经变换了位置,故最终......
  • 21_合并两个有序链表
    21_合并两个有序链表【问题描述】将两个升序链表合并为一个新的升序链表并返回。新链表是通过拼接给定的两个链表的所有节点组成的。示例一:输入:l1=[1,2,4],l2=[1,3,4]输出:[1,1,2,3,4,4]示例二:输入:l1=[],l2=[]输出:[]示例三:输入:l1=[],l2=[0]输出:[0]......
  • 链表高频题
    链表高频题160.相交链表#include<vector>#include<iostream>#include<algorithm>structListNode{intval;ListNode*next;ListNode(intx):val(x),next(NULL){}};classSolution{public:ListNode*getIntersectionNode(Li......
  • 代码随想录算法训练营Day03-链表 | LC203移除链表元素、LC707设计链表、LC206反转链表
    目录前言LeetCode203.移除链表元素思路完整代码LeetCode707.设计链表思路完整代码LeetCode206.反转链表思路完整代码今日总结前言拖延症犯了,哈哈,拖了一天LeetCode203.移除链表元素给你一个链表的头节点head和一个整数val,请你删除链表中所有满足Node.val......
  • 代码随想录算法训练营第三天|203.移除链表元素,707.设计链表,206.反转链表
    203.移除链表元素文章链接:https://programmercarl.com/0203.移除链表元素.html#算法公开课视频讲解:https://www.bilibili.com/video/BV18B4y1s7R9题目出处:https://leetcode.cn/problems/remove-linked-list-elements/卡哥在这里讲解了为什么要使用虚拟头节点,以及使用和不使......
  • 面试题 02.07. 链表相交
    明天回家喽,最近在学习的瓶颈期,感觉学的东西好难,有厌学的心理,但是我相信过了这段煎熬的时期,就好了。classSolution{public:ListNode*getIntersectionNode(ListNode*headA,ListNode*headB){intna=0,nb=0;ListNode*tempA=headA;L......
  • 链表分割 1.2版本
    现有一链表的头指针ListNode* pHead,给一定值x,编写一段代码将所有小于x的结点排在其余结点之前,且不能改变原来的数据顺序,返回重新排列后的链表的头指针。思路:大致可以分为两个区域来存储数据:区域一存储小于36的节点,区域二存储大于36的节点.可以将这两个区域视为两个链表......
  • 算法训练营第三天| 203.移除链表元素、707.设计链表、206.反转链表
    203.移除链表元素状态:完成个人思路:首先令head符合条件,之后判断这个head是否为空,空的话返回空节点;非空的话继续进行。令pre=head;cur=head->next,只要cur非空,就判断cur的值的情况,如果需要删除,就改变pre->next和cur;如果不需要删除就继续检查下一个。看完讲解视频之后的想法:我......
  • 代码随想录算法训练营第三天 | 熟悉链表
    链表的存储方式数组是在内存中是连续分布的,但是链表在内存中可不是连续分布的。链表是通过指针域的指针链接在内存中各个节点。所以链表中的节点在内存中不是连续分布的,而是散乱分布在内存中的某地址上,分配机制取决于操作系统的内存管理。链表的定义template<typenameT>......
  • 力扣 简单 206.反转链表
    文章目录题目介绍题解题目介绍题解法一:双指针在遍历链表时,将当前节点的next改为指向前一个节点。由于节点没有引用其前一个节点,因此必须事先存储其前一个节点。在更改引用之前,还需要存储后一个节点。最后返回新的头引用。代码如下:classSolution{public......