单链表(C语言实现)
链表结构:

SList.h
//--------------------------------------------------------------------------
/*
**功能:应用C语言实现单链表的各项操作
**
**
** 1:建立节点
** 2:打印单链表
** 3:尾插
** 4:尾删
** 5:头插
** 6:头删
** 7:清空整个链表
** 8:获取链表长度
** 9:查找数据
** 10:在某位置后插入数据
** 11:删除某位置的数据
** 12:删除一个无头单链表的非尾节点
** 13:在无头单链表的一个非头节点前插入一个节点
** 14:查找中间节点
** 15:查找倒数第k个节点(要求只能遍历一次)
** 16:倒着打印单链表
** 17:逆置单链表
** 18:合并两个有序链表(合并后依然有序)
** 19:冒泡排序
**
**
** By :Lynn-Zhang
**
*/
//---------------------------------------------------------------------------
#pragma once typedef int DataType; typedef struct SListNode
{
DataType data; // 数据
struct SListNode* next; //指向下一个节点的指针
}SListNode; // 如果要修改链表就必须加引用
SListNode* _BuyNode(DataType x); //建立节点
void PrintSlist(SListNode* pHead); //打印单链表
void PushBack(SListNode* & pHead, DataType x); //尾插(这里用了引用,指明是list的别名,调用时传参,不用传地址)(引用在.c文件中不可用)
//void PushBack(SListNode** pHead, DataType x); // 这里的第一个参数指向链表第一个节点的指针的地址(调用时传参,传的是地址) void PopBack(SListNode* & pHead); //尾删
void PushFront(SListNode* & pHead, DataType x); //头插
void PopFront(SListNode* & pHead); //头删
void DestoryList(SListNode*& pHead); //清空整个链表 int GetSize(SListNode* pHead); //获取链表长度
SListNode* Find(SListNode* pHead, DataType x); //查找数据
void Insert(SListNode* pos, DataType x); //在某位置后插入数据
void Erase(SListNode*& pHead, SListNode* pos); //删除某位置的数据
void DelNonTailNode(SListNode* pos); //删除一个无头单链表的非尾节点
void InsertFrontNode(SListNode* pos, DataType x); // 在无头单链表的一个非头节点前插入一个节点
SListNode* FindMidNode(SListNode* pHead); //查找中间节点
SListNode* FindKNode(SListNode* pHead, int k); //查找倒数第k个节点(要求只能遍历一次)
void PrintTailToHead(SListNode* pHead); //倒着打印单链表(递归) //SListNode* Reverse_(SListNode* pHead); //逆置单链表(需要接收返回值),原链表会被改
void Reverse(SListNode*& pHead); // 将原链表逆置 SListNode* Merge(SListNode* pHead1, SListNode* pHead2); //合并两个有序链表(合并后依然有序)(递归)
void Sort(SListNode* pHead); //冒泡排序
SList.cpp
#include"SList.h" #include <stdio.h>
#include<assert.h>
#include <malloc.h> SListNode* _BuyNode(DataType x) //建立节点
{
SListNode* tmp = (SListNode*)malloc(sizeof(SListNode));
tmp->data = x;
tmp->next = NULL; return tmp;
}
void PrintSlist(SListNode* pHead) // 打印单链表
{
SListNode* cur = pHead;
while (cur)
{
printf("%d->", cur->data);
cur = cur->next;
} printf("NULL\n");
}
//void PushBack(SListNode** ppHead, DataType x) //尾插
//{
// assert(ppHead);
// // 1.空
// // 2.不为空
// if(*ppHead == NULL)
// {
// *ppHead = _BuyNode(x);
// }
// else
// {
// // 找尾
// SListNode* tail = *ppHead;
// while(tail->next != NULL)
// {
// tail = tail->next;
// }
//
// tail->next = _BuyNode(x);
// }
//}
void PushBack(SListNode* & pHead, DataType x) //尾插
{
// 1.空
// 2.不为空
if (pHead == NULL)
{
pHead = _BuyNode(x);
}
else
{
// 找尾
SListNode* tail = pHead;
while (tail->next != NULL)
{
tail = tail->next;
} tail->next = _BuyNode(x);
}
}
void PopBack(SListNode* & pHead) // 尾删
{
//
// 1.空
// 2.一个节点
// 3.多个节点
//
if (pHead == NULL)
{
return;
}
else if (pHead->next == NULL)
{
free(pHead);
pHead = NULL;
}
else
{
SListNode* tail = pHead;
SListNode* prev = NULL;
while (tail->next)
{
prev = tail;
tail = tail->next;
} free(tail);
prev->next = NULL;
}
}
void PushFront(SListNode* & pHead, DataType x) //头插
{
// 1.空
// 2.不空
if (pHead == NULL)
{
pHead = _BuyNode(x);
}
else
{
SListNode* tmp = _BuyNode(x);
tmp->next = pHead;
pHead = tmp;
}
}
void PopFront(SListNode*& pHead) //头删
{
//
// 1.空
// 2.一个节点
// 3.一个以上的节点
//
if (pHead == NULL)
{
return;
}
else if (pHead->next == NULL)
{
free(pHead);
pHead = NULL;
}
else
{
SListNode* tmp = pHead;
pHead = pHead->next; free(tmp);
}
}
void DestoryList(SListNode*& pHead) //清空整个链表
{
SListNode* cur = pHead;
while (cur)
{
SListNode* tmp = cur;
cur = cur->next;
free(tmp);
} pHead = NULL;
} int GetSize(SListNode* pHead) //获取链表长度
{
assert(pHead);
SListNode* cur = pHead;
int count = ;
while (cur)
{
count++;
cur = cur->next;
}
return count;
}
SListNode* Find(SListNode* pHead, DataType x) //查找节点
{
SListNode* cur = pHead;
while (cur)
{
if (cur->data == x)
{
return cur;
}
cur = cur->next;
}
return NULL;
}
void Insert(SListNode* pos, DataType x) // 某位置后插入节点
{
assert(pos); SListNode* tmp = _BuyNode(x);
tmp->next = pos->next;
pos->next = tmp;
}
void Erase(SListNode*& pHead, SListNode* pos) //删除某位置的节点
{
assert(pos);
assert(pHead); //pos为头结点
if (pHead == pos)
{
pHead = pHead->next;
free(pos);
return;
}
////
SListNode* prev = pHead;
while (prev)
{
if (prev->next == pos)
{
prev->next = pos->next;
free(pos);
break;
}
prev = prev->next;
}
}
void DelNonTailNode(SListNode* pos) //// 删除一个无头单链表的非尾节点
{
assert(pos);
assert(pos->next);
SListNode* del = pos->next;
SListNode* dnext = del->next;
pos->data = del->data;
pos->next = dnext;
free(del);
}
void InsertFrontNode(SListNode* pos, DataType x) // 在无头单链表的一个非头节点前插入一个节点
{
assert(pos); SListNode* tmp = _BuyNode(pos->data);
tmp->next = pos->next;
pos->next = tmp;
pos->data = x;
} void Sort(SListNode* pHead) //冒泡排序
{ assert(pHead);
int size = GetSize(pHead);
for (int i = ; i < size - ; i++)
{
SListNode* left = pHead;
SListNode* right = pHead->next;
for (int j = ; j < size - i - ; j++)
{
if (left->data>right->data)
{
int tmp = left->data;
left->data = right->data;
right->data = tmp;
}
right = right->next;
left = left->next;
}
}
} SListNode* FindMidNode(SListNode* pHead) //查找中间节点
{
SListNode* fast = pHead;
SListNode* slow = pHead;
while (fast&&fast->next)
{
slow = slow->next;
fast = fast->next->next;
}
return slow;
}
SListNode* FindKNode(SListNode* pHead, int k) //查找倒数第k个节点
{
SListNode* fast = pHead;
SListNode* slow = pHead;
while (fast && k--)
{
fast = fast->next;
}
if (k > )
{
return NULL;
}
while (fast)
{
slow = slow->next;
fast = fast->next;
}
return slow;
}
void PrintTailToHead(SListNode* pHead) //倒着打印单链表(递归)
{
if (pHead)
{
PrintTailToHead(pHead->next);
printf("%d ", pHead->data);
}
}
//SListNode* Reverse_(SListNode* pHead) //逆置单链表(需要接收返回值)原链表会被改
//{
// SListNode* cur = pHead;
// SListNode* newHead = NULL;
// while (cur)
// {
// SListNode* tmp = cur;
// cur = cur->next;
// tmp->next = newHead;
// newHead = tmp;
// }
// return newHead;
//}
void Reverse(SListNode*& pHead) //逆置单链表 (无需返回值)
{
SListNode* cur = pHead;
SListNode* newHead = NULL;
while (cur)
{
SListNode* tmp = cur;
cur = cur->next;
tmp->next = newHead;
newHead = tmp;
}
pHead = newHead;
//return newHead;
}
SListNode* Merge(SListNode* pHead1, SListNode* pHead2) //合并两个有序链表(合并后依然有序)递归
{
if (pHead1 == NULL)
return pHead2;
else if (pHead2 == NULL)
return pHead1;
SListNode* pMergedHead = NULL;
if (pHead1->data < pHead2->data)
{
pMergedHead = pHead1;
pMergedHead->next = Merge(pHead1->next, pHead2);
}
else
{
pMergedHead = pHead2;
pMergedHead->next = Merge(pHead1, pHead2->next);
}
return pMergedHead;
}
Test.cpp
#include "SList.h"
#include<stdlib.h>
//测试用例
void Test1()
{
// 尾插 打印 尾删 头插 头删 清空链表
SListNode* list = NULL;
PushBack(list, );
PushBack(list, );
PushBack(list, );
PushBack(list, );
PrintSlist(list);
PopBack(list);
PrintSlist(list);
PushFront(list,);
PrintSlist(list);
PopFront(list);
PrintSlist(list);
DestoryList(list);
PrintSlist(list);
}
void Test2()
{
// 查找节点 在某位置插入节点 删除某位置节点
SListNode* list = NULL;
PushBack(list, );
PushBack(list, );
PushBack(list, );
PushBack(list, );
PrintSlist(list);
SListNode* pos = Find(list, );
Insert(pos, );
PrintSlist(list);
Erase(list, Find(list, ));
PrintSlist(list); }
void Test3()
{
SListNode* list = NULL;
PushBack(list, );
PushBack(list, );
PushBack(list, );
PushBack(list, );
PushBack(list, );
PushBack(list, );
PrintSlist(list);
// 删除一个无头单链表的非尾节点
/*SListNode* pos = Find(list, 2);
DelNonTailNode(pos);
PrintSlist(list);*/ // 在无头单链表的一个非头节点前插入一个节点
/*SListNode* pos = Find(list, 2);
InsertFrontNode(pos, 0);
PrintSlist(list);*/ //查找中间节点
//PrintSlist(FindMidNode(list)); //查找倒数第k个节点
//SListNode* ret = FindKNode(list, 2);
//PrintSlist(ret); //倒着打印单链表(递归)
//PrintTailToHead(list); //逆置单链表
//SListNode* ret = Reverse(list);
//PrintSlist(ret);
//PrintSlist(Reverse_(list));
//PrintSlist(list); }
void Test4()
{ //合并两个有序链表(合并后依然有序)
SListNode* list = NULL;
PushBack(list, );
PushBack(list, );
PushBack(list, );
PushBack(list, );
PrintSlist(list);
Sort(list);
PrintSlist(list); /*SListNode* list1 = NULL;
PushBack(list1, 2);
PushBack(list1, 3);
PushBack(list1, 3);
PushBack(list1, 0);
PrintSlist(list);
Sort(list1);
PrintSlist(list1); SListNode* ret = Merge(list, list1);
PrintSlist(ret);
PrintSlist(list);
PrintSlist(list1);*/
}
int main()
{
//Test1();
//Test2();
//Test3();
Test4();
system("pause");
return ;
}
单链表(C语言实现)的更多相关文章
- 单链表 C语言 学习记录
概念 链接方式存储 链接方式存储的线性表简称为链表(Linked List). 链表的具体存储表示为: 用一组任意的存储单元来存放线性表的结点(这组存储单元既可以是连续的,也可以是不连续的). 链表中 ...
- 带头结点的循环单链表----------C语言
/***************************************************** Author:Simon_Kly Version:0.1 Date: 20170520 D ...
- 带头节点的单链表-------C语言实现
/***************************************************** Author:Simon_Kly Version:0.1 Date:20170520 De ...
- 不带头结点的单链表------C语言实现
File name:no_head_link.c Author:SimonKly Version:0.1 Date: 2017.5.20 Description:不带头节点的单链表 Funcion L ...
- 单链表c语言实现的形式
包括初始化,创建,查询,长度,删除,清空,销毁等操作 代码如下: #include<stdio.h> #include<stdlib.h> //定义单链表的数据类型 typed ...
- 数据结构-多级指针单链表(C语言)
偶尔看到大一时候写了一个多级链表,听起来好有趣,稍微整理一下. 稍微注意一下两点: 1.指针是一个地址,他自己也是有一个地址.一级指针(带一个*号)表示一级地址,他自身地址为二级地址.二级指针(带两个 ...
- 数据结构与算法分析——C语言描述 第三章的单链表
数据结构与算法分析--C语言描述 第三章的单链表 很基础的东西.走一遍流程.有人说学编程最简单最笨的方法就是把书上的代码敲一遍.这个我是头文件是照抄的..c源文件自己实现. list.h typede ...
- 数据结构算法C语言实现(二)---2.3线性表的链式表示和实现之单链表
一.简述 [暂无] 二.头文件 #ifndef _2_3_part1_H_ #define _2_3_part1_H_ //2_3_part1.h /** author:zhaoyu email:zh ...
- C语言实现单链表-03版
在C语言实现单链表-02版中我们只是简单的更新一下链表的组织方式: 它没有更多的更新功能,因此我们这个版本将要完成如下功能: Problem 1,搜索相关节点: 2,前插节点: 3,后追加节点: 4, ...
- C语言实现单链表-02版
我们在C语言实现单链表-01版中实现的链表非常简单: 但是它对于理解单链表是非常有帮助的,至少我就是这样认为的: 简单的不能再简单的东西没那么实用,所以我们接下来要大规模的修改啦: Problem 1 ...
随机推荐
- Ubuntu安装sublime test 3 (Build 3126)
Ubuntu下 Sublime Text 3 (Build 3143) 存在一些bug........ 满心欢喜地更新后, 又默默换回Build 3126 1. 安装 sudo apt-get upd ...
- Nginx日志配置与切割
访问日志主要记录客户端访问Nginx的每一个请求,格式可以自定义.通过访问日志,你可以得到用户地域来源.跳转来源.使用终端.某个URL访问量等相关信息. Nginx中访问日志相关指令主要有两条,一条是 ...
- 《HBase in Action》 第二章节的学习总结 ---- HBase基本组成
准备工作:采用的HBase版本是:CDH4.5,其中的Hadoop版本是:hadoop-2.0.0-cdh4.5.0:HBase版本是:hbase-0.94.6-cdh4.5.0: Hbase的配置文 ...
- 【SQLServer2008】之Telnet以及1433端口设置
Telnet步骤: 一.首先进入Win7控制面板,可以从开始里找到或者在桌面上找到计算机,点击进入里面也可以找到控制面板,如下图: 二.进入控制面板后,我们再找到“程序和功能”并点击进入,如下图所示: ...
- 走进科学之揭开神秘的"零拷贝"!
"零拷贝"这三个字,想必大家多多少少都有听过吧,这个技术在各种开源组件中都使用了,比如kafka,rocketmq,netty,nginx等等开源框架都在其中引用了这项技术 ...
- 二级导航内容均分--jquery
这个是去年做过的一个项目中的算法,个人感觉还可以,所以拿出来分享下. 背景:头部导航二级导航有些内容太长,一列的话太过难看,就要分成两列,要做到按块尽量均分,排列顺序没有限制. 原理: 1.把各个二级 ...
- XtraBackup备份mysql5.1.73
一.基础介绍 mysql5.1在源码中配备了两个版本的innodb存储引擎源码:innobase和innodb_plugin,编译安装的时候可以通过参数--with-plugins=innobase, ...
- ASP.NET动态网站制作(18)-- jq作业讲解及知识补充
前言:这节课主要讲解js及jq作业,并在作业讲解完后补充关于jQuery的一些知识点. 内容: 1.作业讲解:计算器那一块考虑的各种情况还不算完善,只实现了基本的功能,还需多多练习使用jQuery. ...
- php扩展安装phpize
安装php(fastcgi模式)的时候,常常有这样一句命令:/usr/local/webserver/php/bin/phpize 一.phpize是干嘛的? phpize是什么东西呢?php官方的说 ...
- ios开发:如何加载大量图片 相册示例
本文转载至 http://www.cnblogs.com/xiongqiangcs/archive/2013/06/13/3134486.html 1. Create a NSOperationQ ...