c语言 增删查 案例,C语言实现单链表的增删查改

#include

#include

#include"linklist.h"

#define Test_Header printf("\n-----%s-----\n",__FUNCTION__);

//初始化函数

void linklistInit(LinkNode **head)

{

*head = NULL;

}

//创建新节点函数

LinkNode *CreateNode(LType value)

{

//为新节点申请空间

LinkNode *new_node = (LinkNode*)malloc(sizeof(LinkNode));

//给新节点赋值

new_node->data = value;

//将新节点的next指向空

new_node->next = NULL;

return new_node;

}

//销毁一个节点

void DestroyNode(LinkNode *node)

{

free(node);

}

//顺序打印链表元素

void linklistPrint(LinkNode *head)

{

if(head == NULL)

{

//空链表无需打印

return;

}

LinkNode *cur = head;

//遍历链表

while(cur != NULL)

{

//打印元素和其对应的地址

printf("%c|%p\n",cur->data,cur);

//移动cur,以达到遍历链表的目的

cur = cur->next;

}

printf("\n\n");

}

//逆序打印链表(递归思想)

void linklistReversePrint(LinkNode *head)

{

if(head == NULL)

{

//空链表无需打印,也是递归的出口

return;

}

linklistReversePrint(head->next);

printf("%c|%p ",head->data,head);

printf("\n");

}

//尾插函数

LinkNode *linklistPushBack(LinkNode **head,LType value)

{

//非法输入

if(head == NULL)

{

return NULL;

}

//空链表

if(*head == NULL)

{

//直接创建一个新的节点完成元素插入

*head = CreateNode(value);

return NULL;

}

else

{

LinkNode *cur = *head;

//遍历链表,让cur指向最后一个元素

while(cur->next != NULL)

{

cur = cur->next;

}

//创建一个新节点

LinkNode *new_node = CreateNode(value);

//将最后一个元素的next指向新节点

cur->next = new_node;

return new_node;

}

}

//尾删函数

void linklistPopBack(LinkNode **head)

{

//非法输入

if(head == NULL)

{

return;

}

//空链表没有可删除的元素

if(*head == NULL)

{

return;

}

//只有一个元素

if((*head)->next == NULL)

{

//直接删除节点

DestroyNode(*head);

//将头结点置空

*head = NULL;

return;

}

else

{

LinkNode *cur = *head;

//遍历链表,使cur指向倒数第二个元素

while(cur->next->next != NULL)

{

cur = cur->next;

}

//创建指针指向最后一个元素,即我们需要删除的元素

LinkNode *to_delete = cur->next;

//将该节点销毁

DestroyNode(to_delete);

//将倒数第二个元素的next指向空

cur->next = NULL;

}

return;

}

//头插函数

void linklistPushFront(LinkNode **head,LType value)

{

//非法输入

if(head == NULL)

{

return;

}

//空链表

if(*head == NULL)

{

//直接创建一个新节点完成插入

*head = CreateNode(value);

return;

}

else

{

//创建一个新的指针指向头结点

LinkNode *new_node = *head;

//创建一个新的头结点

*head = CreateNode(value);

//将新的头结点的next指向旧的头结点

(*head)->next = new_node;

}

return;

}

//头删函数

void linklistPopFront(LinkNode **head)

{

//非法输入

if(head == NULL)

{

return;

}

//空链表没有可删除的元素

if(*head == NULL)

{

return;

}

else

{

//创建一个新的指针指向第二个元素

LinkNode *new_node = (*head)->next;

//将头结点的next指向空

(*head)->next = NULL;

//删除该头结点

DestroyNode(*head);

//将第二个元素设置成新的头结点

*head = new_node;

}

return;

}

//查找链表中指定元素的地址

LinkNode *linklistFind(LinkNode *head,LType to_find)

{

int count = 0;

LinkNode *find = head;

//空链表

if(head == NULL)

{

return;

}

else

{

//循环遍历链表

for(;find->next != NULL;find = find->next)

{

if(find->data == to_find)

{

count++;

//找到了返回该元素的地址

return find;

}

}

}

//如果count计数为0,说明没有链表中不存在想要查找的元素

if(count == 0)

{

printf("this value is non-existence\n");

}

//没找到返回空

return NULL;

}

//在指定位置之前插入指定元素(遍历)函数

//时间复杂度为O(n)

void linklistInsertBefore(LinkNode **head,LinkNode *pos,LType value)

{

//非法输入

if(head == NULL)

{

return;

}

//空链表

if(*head == NULL)

{

//直接创建一个新的节点

*head = CreateNode(value);

return;

}

//如果是头结点位置

if(pos == *head)

{

//则进行头插

linklistPushFront(head,value);

return;

}

//如果为空

if(pos == NULL)

{

//则进行尾插

linklistPushBack(head,value);

return;

}

else

{

LinkNode *cur = *head;

//遍历链表

while(cur->next != NULL)

{

//cur的下一个位置就是pos

if(cur->next == pos)

{

//创建一个指针,以value值创建节点

LinkNode *pre = CreateNode(value);

//将cur的next修改指向新的节点的位置

cur->next = pre;

//将新节点的next指向pos,就在pos位置之前插入了新元素

pre->next = pos;

return;

}

//将cur移向下一个元素,以达到遍历链表的目的

cur = cur->next;

}

}

}

//在指定位置之前插入指定元素(不遍历)函数

//时间复杂度为O(1)

void linklistInsertBefore1(LinkNode **head,LinkNode *pos,LType value)

{

//非法输入

if(head == NULL)

{

return;

}

//空链表

if(*head == NULL)

{

//直接创建一个新的节点

*head = CreateNode(value);

return;

}

//如果是头结点位置

if(pos == *head)

{

//则进行头插

linklistPushFront(head,value);

return;

}

//如果位置为空

if(pos == NULL)

{

//则进行尾插

linklistPushBack(head,value);

return;

}

else

{

//定义一个新指针指向pos的下一个位置

LinkNode *cur = pos->next;

//用pos位置的值创建一个新的节点

LinkNode *new_node = CreateNode(pos->data);

//将pos位置的值修改为value

pos->data = value;

//将pos的next指向新的节点

pos->next = new_node;

//将新节点的next指向pos的next,即指向cur

new_node->next = cur;

}

}

//在指定位置之后插入指定元素

void linklistInsertAfter(LinkNode **head,LinkNode *pos,LType value)

{

//非法输入

if(head ==NULL)

{

return;

}

//空链表

if((*head) == NULL)

{

//直接以value值创建一个头结点

*head = CreateNode(value);

return;

}

//如果pos位置为空

if(pos == NULL)

{

//则进行尾插

linklistPushBack(head,value);

return;

}

//如果pos为头结点的位置

if(pos == *head)

{

//则进行头插

linklistPushFront(head,value);

return;

}

else

{

//创建一个新的指针指向头结点

LinkNode *cur = *head;

//遍历链表

while(cur->next != NULL)

{

//cur的下一个位置就是pos

if(cur->next == pos)

{

//以value值创建一个新的节点

LinkNode *new_node = CreateNode(value);

//新节点的next指向pos位置的next

new_node->next = pos->next;

//pos的next修改指向新的节点

pos->next = new_node;

}

//移动cur

cur = cur->next;

}

}

}

//删除指定位置的元素(遍历)函数

//时间复杂度为O(n)

void linklistErase(LinkNode **head,LinkNode *pos)

{

//非法输入

if(head == NULL)

{

return;

}

//空链表

if(*head == NULL)

{

return;

}

//如果pos位置为空

if(pos == NULL)

{

//则进行尾删

linklistPopBack(head);

return;

}

//如果pos为头结点的位置

if(pos == *head)

{

//则进行头删

linklistPopFront(head);

return;

}

else

{

//创建新的指针指向头结点

LinkNode *cur = *head;

//遍历链表,遍历完成以后cur的下一个位置就是pos

while(cur->next != pos)

{

cur = cur->next;

}

//将cur的next指向pos的next

cur->next = pos->next;

//销毁pos节点

DestroyNode(pos);

}

}

删除指定位置的元素(遍历)函数

//时间复杂度为O(1)

void linklistErase2(LinkNode **head,LinkNode *pos)

{

//非法输入

if(head == NULL)

{

return;

}

//空链表无法删除

if(*head == NULL)

{

return;

}

//如果pos位置为空

if(pos == NULL)

{

//则进行尾删

linklistPopBack(head);

return;

}

//如果pos为头结点位置

if(pos == *head)

{

//则进行头删

linklistPopFront(head);

return;

}

else

{

//创建一个新的指针指向pos的next

LinkNode *to_delete = pos->next;

//将pos的下一个位置的元素赋给pos

pos->data = to_delete->data;

//再将pos的next指向其下一个元素的next

pos->next = to_delete->next;

//将pos的下一个位置节点删除

DestroyNode(to_delete);

}

}

//删除指定元素,若存在多个元素则只删除第一个函数

void linklistRemove(LinkNode **head,LType to_delete)

{

//非法输入

if(head == NULL)

{

return;

}

//空链表没有可删除的元素

if(*head == NULL)

{

return;

}

//如果头结点的元素是要删除的元素

if((*head)->data == to_delete)

{

//则进行头删

linklistPopFront(head);

return;

}

LinkNode *cur = *head;

//遍历链表

while(cur != NULL && cur->next != NULL)

{

//要删除的元素是cur的下一个元素

if(cur->next->data == to_delete)

{

//定义一个新的指针指向cur的下一个元素(待删除元素)的位置

LinkNode *to_remove = cur->next;

//将cur的next指向其下一个元素(待删除元素)的下一个位置

cur->next = to_remove->next;

//删除新的节点(即一开始定义的指向待删除元素的指针)

DestroyNode(to_remove);

return;

}

cur = cur->next;

}

}

//判断链表是否为空链表

int linklistEmpty(LinkNode *head)

{

//为空返回0否则返回1

return head == NULL?0:1;

}

//求链表中元素个数,返回元素个数

size_t linklistSize(LinkNode *head)

{

//空链表返回0

if(head == NULL)

{

return 0;

}

size_t count = 0;

LinkNode *cur = head;

//遍历链表

for(;cur != NULL;cur = cur->next)

{

count++;

}

return count;

}

//尾插的测试函数

void TestPushBack()

{

Test_Header;

//初始化链表

linklistInit(&head);

//尾插a b c d

linklistPushBack(&head,'a');

linklistPushBack(&head,'b');

linklistPushBack(&head,'c');

linklistPushBack(&head,'d');

linklistPrint(head);

}

//尾删的测试函数

void TestPopBack()

{

Test_Header;

//尾删3次

linklistPopBack(&head);

linklistPopBack(&head);

linklistPopBack(&head);

linklistPrint(head);

}

//头插的测试函数

void TestPushFront()

{

Test_Header;

//头插b c d

linklistPushFront(&head,'b');

linklistPushFront(&head,'c');

linklistPushFront(&head,'d');

linklistPrint(head);

}

//头删的测试函数

void TestPopFront()

{

Test_Header;

//头删3次

linklistPopFront(&head);

linklistPopFront(&head);

linklistPopFront(&head);

linklistPrint(head);

}

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/442863.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

模拟注册用户,按照以下要求实现相关功能:

package Day08;import java.util.Scanner;/*** 模拟注册用户,按照以下要求实现相关功能:* a. 提示用户在控制台输入手机号码,并接收。* b. 判断用户输入的是否都是手机号码(11位纯数字),* 如果不是手机号码,则提示用户“注册用户失败”。* c.…

FileWriter写入和Scanner录入的简单操作

import java.io.*; import java.util.Scanner;/*** 用户录入用户名和密码,存储到文件中,* 用户名和密码独占一行*/ public class Write {public static void main(String[] args) throws IOException {FileWriter fw new FileWriter("IoFile\\a.tx…

c语言实验题数组逆序,【C语言】利用栈将数组中字符串逆序

该楼层疑似违规已被系统折叠 隐藏此楼查看此楼#include"stdio.h"#include"stdlib.h"#define STACK_INIT_SIZE 100#define STACKINCREMENT 10typedef struct{char *base;char *top;int stacksize;}SqStack;main(){SqStack S;char a[4];int i;InitStack(&…

IO字节缓冲流的最简单读写源码

import java.io.*;public class mode4 {public static void main(String[] args) throws IOException {//利用缓冲流去拷贝文件//创建一个字节缓冲输入流//在底层默认创建了一个长度为8192的字节数组BufferedInputStream bis new BufferedInputStream(new FileInputStream(&qu…

c语言运算符ppt,C语言知识学习运算符.ppt

C语言知识学习运算符.ppt 第三章,C语言运算符,回顾,变量和常量的含义 熟悉基本数据类型 - int、char、float 和 double 使用算术运算符 理解类型转换 熟练使用 scanf 和 printf 函数,课程目标,算术运算符 增量运算符 逻辑运算符 关系运算符 按位运算符 C的特殊运算符 --“” “…

java用数组实现随机不重复抽奖

import java.util.Random;/*** 用奖池随机抽奖*/ public class mode2 {public static void main(String[] args) {int[] arr {888, 588, 10000, 1000, 2}; //奖池int[] arr1 new int[arr.length]; //一已经中奖的奖池int intr;//用于接收随机数int count 0;//用于已经中奖…

c语言常用算法累加法例题,C语言第三次模拟练习题部分解答.docx

单项选择号:13334若有如下语句int x3;do {printf (,,%d\n/,, x-2) ;}while(! (--x));则上面程序段oA、输出的是1B、输出的是1和-2C、输出的是3和0D、是死循环答案:B解答:循环变量x初值为3. Do-while是先执行…

java用map集合实现随机抽奖源码

import java.util.HashMap; import java.util.Random;//用map实现抽奖 public class demo3 {public static void main(String[] args) {int[] arr {888, 588, 10000, 1000, 2};HashMap<Integer, Integer> map new HashMap<Integer, Integer>();//中奖的奖池Rando…

c语言二叉树图形输出,C语言数据结构树状输出二叉树,谁能给详细的解释一下...

该楼层疑似违规已被系统折叠 隐藏此楼查看此楼void TranslevelPrint(Bitree bt){struct node{Bitree vec[MAXLEN]; //存放树结点int layer[MAXLEN]; //结点所在的层int locate[MAXLEN]; //打印结点的位置int front,rear;}q;int i,j,k;int nLocate;j 1;k 0;q.front 0;q.rear …

java递归统计一个文件夹含子文件夹里文件不同后缀的出现次数

/*** 统计一个文件夹中不同文件出现的次数*/ public class demo1 {public static void main(String[] args) {File file new File("IoFile");HashMap<String, Integer> mp new HashMap<>();getCount(mp, file);System.out.println(mp);}private static…

java递归遍历删除文件

import java.io.File;/* 遍历递归删除文件夹类的所有文件*/ public class demo {public static void main(String[] args) {File file new File("D:\\BaiduNetdiskDownload");dileteDir(file);}private static void dileteDir(File file) {File[] files file.listF…

ionic判断android版本,$ionicplatform 判断是android还是ios?

一只名叫tom的猫安装环境首先应该安装好 node.js (略)&#xff0c;然后安装cordova、ionic等sudo npm install -g cordova ionic ios-sim创建不同类型的项目目前可以用blank&#xff0c;tabs&#xff0c;sidemenu三种ionic start myApp tabs常用插件cordova plugin add com.ion…

java用scanner 和random的一个小案例

import java.util.ArrayList;/*** 存放单词的实体类&#xff0c;为附体类&#xff0c;需要运行mymain 主入口*/ public class Entity {private String ecglish;//英语单词private String chaina;//中文解释private String day; //属于第几天的单词private ArrayList list new …

android onscrolllistener判断到底部,判断RecyclerView是否滑动到底部

判断RecyclerView是否滑动到底部recyclerView.addOnScrollListener(new RecyclerView.OnScrollListener() {Overridepublic void onScrollStateChanged(NonNull RecyclerView recyclerView, int newState) {super.onScrollStateChanged(recyclerView, newState);}Overridepubli…

二位数组的随机生成,遍历,求和,反转。和两个变量的^反转 源码

import java.util.Random;/*** derf*/ public class Operate {public static void main(String[] args) {int[][] arr getArr(20);//获得二维一维长度相同的随机数数组forarr(arr);//遍历传入的数组sumarr(arr);//对二维数组求和int[] arr1 {1, 2, 3, 4, 5, 6, 7, 8, 9};fZar…

robolectric android studio,Android Studio + Robolectric + AndroidAnnotations 根本框架

记录一下&#xff0c;使用的 Android Studio 版本是 0.8.2 (Beta)在 Project 目录下的 build.gralde 文件中的 dependencies 添加二行classpath org.robolectric:robolectric-gradle-plugin:0.classpath com.neenbedankt.gradle.plugins:android-apt:1.引入这二个插件 robolect…

二维数组:随机生产,遍历,判断两个数组一维二维长度,和内容是否一致

import java.util.Random;/*** 1&#xff0c;定义第一个方法&#xff0c;传入数组长度&#xff0c;返回一个1维和2维长度都完全相同的数组* 2.定义一个方法&#xff0c;传入两个数二维组&#xff0c;判断两个数组是否完全一致&#xff1a;一维&#xff0c;二维长度&#xff0c;…

字符缓冲输入流,高效读取整行数据

import java.io.BufferedReader; import java.io.FileReader;/* 字符缓冲输入流&#xff0c;高效读取整行数据*/ public class Writer {public static void main(String[] args) {try (BufferedReader br new BufferedReader(new FileReader("IoFile\\a.txt"))) {St…

华为鸿蒙等不急了,华为最强巨作,鸿蒙OS+六摄+麒麟985,网友:等不及了!

原标题&#xff1a;华为最强巨作&#xff0c;鸿蒙OS六摄麒麟985&#xff0c;网友&#xff1a;等不及了&#xff01;华为最强旗舰机一般公认是Mate系列&#xff0c;虽然华为跟三星一样&#xff0c;也是走双旗舰&#xff0c;Mate和P系列都是旗舰机&#xff0c;但是华为和三星有所…

华为鸿蒙2.0操作页面,华为鸿蒙2.0开面界面确认,这一变化你可懂

最近一段时间关于华为鸿蒙手机端操作系统的消息非常多&#xff0c;但是由于目前仅是测试阶段&#xff0c;我们无法全面的了解这个全新的操作系统长什么样。在操作上有何不同等等&#xff0c;在这样的前提之下很多参与内测有朋友时不时的就会放出一些信息。5月5日有人放出了华为…