单链表以及其基本操作
2018-02-02 22:00
344 查看
链表以及基本操作
1. 链表是一种链式存储的线性表,每个存储单元称为结点
链表是相互连接起来的存储单元,一个存储单元包含两部分
一部分表示的是指向下一个存储单元的指针,另一部分表示的是的存储单元中的数据元素。
2. 接下来就进行一些基本的链表操作
(1)链表的建立
//链表类型在头文件中的定义
typedef int DataType;
typedef struct SListNode
{
DataType _data;
struct SListNode* _pNext;
// 指向下一个结点的指针
}Node, *PNode;
//开辟空间,并初始化
PNode BuySListNode(DataType data)
{
PNode node = (Node*)malloc(sizeof(Node));//开辟一个Node类型的结点的空间
node->_data = data;
node->_pNext = NULL;
return node;
}
// 尾插
void SListPushBack(PNode*ppHead,
DataType data)
{
assert(ppHead);
if (NULL == *ppHead)
{
*ppHead = BuySListNode(data);
}
else
{
PNode pTail = *ppHead;
while (pTail->_pNext)
{
pTail = pTail->_pNext;
}
pTail->_pNext = BuySListNode(data);
}
}
// 头插
void SListPushFront(PNode*
ppHead,
DataType data)
{
assert(ppHead);
PNode pnewnode = BuySListNode(data);//创建一个新的头结点
pnewnode->_pNext = *ppHead;//更新头结点
*ppHead = pnewnode;
}
(2) 链表的特殊位置以及指定位置的插入和删除
// 尾删
void SLis
4000
tPopBack(PNode*
ppHead)
{
assert(ppHead);
PNode pTail = *ppHead;
PNode pre =
NULL;
while (pTail ==
NULL)//为空时,直接返回
{
printf("链表为空");
return;
}
if (pTail->_pNext ==
NULL)//有一个结点时,释放掉一个结点
{
free(pTail);
pTail = NULL;
}
else if (pTail->_pNext)//为多个时,借用pre来更新链表
{
pre = pTail;
pTail->_pNext = pTail;
}
free(pTail);
pre->_pNext = NULL;
}
// 头删
void SListPopFront(PNode*
ppHead)
{
assert(ppHead);
while (*ppHead ==
NULL)
{
printf("链表为空");
return;
}
PNode pdel = *ppHead;//pdel指向头结点
*ppHead = pdel->_pNext;//改变头结点的位置
free(pdel);
}
// data插入在pos之前
void SListInsert(PNode*
ppHead,
PNode pos,
DataType data)// 1 2 3(5) 4-------》pos为4,data为5
{
assert(ppHead);
PNode pcur = *ppHead;
PNode pnewnode = BuySListNode(data);
if (pcur==
pos)//当pos为头结点时
{
SListPushFront(ppHead,
data);//头插
}
if (pcur->_pNext !=
pos)//后移
{
pcur = pcur->_pNext;
}
else
{
pcur->_pNext = pnewnode;//3指向5
pnewnode->_pNext = pos;//5指向4
}
}
// 删除链表中pos位置的结点
void SListErase(PNode*
ppHead,
PNode pos)// 1 2 3 4---->删除pos为3的结点
{
assert(ppHead);
PNode pcur = *ppHead;
PNode pre = *ppHead;
if(pcur==NULL||pos==NULL)
{
printf("无法删除");
}
if (pcur ==
pos)//当pos为头结点时
{
SListPopFront(ppHead);//头删
}
else
{
PNode pre = *ppHead;
while (pre&&pre->_pNext !=
pos)
{
pre = pre->_pNext;
}
if (pre)
{
pre->_pNext = pos->_pNext;//更新链表
}
free(pos);
}
(3)其余的操作
// 在链表中查找元素data,返回该结点在链表中的位置
PNode Find(PNode pHead,
DataType data)
{
assert(pHead);
PNode pcur =
pHead;
while (pcur)
{
if (pcur->_data ==
data)
{
return pcur;
}
pcur = pcur->_pNext;
}
return NULL;
}
// 获取链表中结点的个数
int Size(PNode pHead)
{
PNode pcur = pHead;
assert(pHead);
int count;
while (pcur)
{
count++;
pcur = pcur->p_Next;
}
return count;
}
// 判断链表是否为空,若为空,返回true,否则返回false
size_t Empty(PNode pHead)
{
assert(pHead);
if (pHead ==
NULL)
{
return 1;
}
else
return 0;
}
// 销毁单链表
void SListDestroy(PNode * ppHead)
{
assert(ppHead);
PNode pre = NULL;//用于更新链表
PNode pcur = *ppHead;
while (pcur)
{
pre = pcur;
pcur->_pNext = pcur;
}
free(pcur);
free(pre);
}
// 打印单链表
void SListPrint(PNode pHead)
{
assert(pHead);
PNode pcur = pHead;
while (pcur)
{
printf("->%d", pcur->_data);
}
printf("\n");
}
3. 测试函数
#include "linklist.h"
int main()
{
Node* L=NULL;//L为指向链表的指针
Node *pos = L;//pos为二级指针
pos = pos->_pNext;
BuySListNode(0);
SListPushBack(&L, 1);//需要传指针的地址,因为需要对链表会有内容的改变
SListPushBack(&L, 2);
SListPushBack(&L, 3);
SListPushBack(&L, 4);
SListPushBack(&L, 5);
SListPrint(&L);
SListPopBack(&L);
SListPrint(&L);
SListPushFront(&L, 0);
SListPrint(&L);
SListPopFront(&L);
// 在链表中查找元素data,返回该结点在链表中的位置
Find(&L, 3);
// data插入在pos之前
SListInsert(&L, pos, 8);
SListPrint(&L);
SListErase(&L, pos);
SListPrint(L);
// 获取链表中结点的个数
Size(L);
// 判断链表是否为空,若为空,返回true,否则返回false
Empty(L);
// 销毁单链表
SListDestroy(&L);
system("pause");
return 0;
}
4.头文件
#include"stdio.h"
#include"assert.h"
#include"windows.h"
#ifndef _LINKLIST_H__
#define _LINKLIST_H__
//链表类型在头文件中的定义
typedef int DataType;
typedef struct SListNode
{
DataType _data;
struct SListNode* _pNext;
// 指向下一个结点的指针
}Node, *PNode;
// 尾插
void SListPushBack(PNode*ppHead,
DataType data);
// 尾删
void SListPopBack(PNode* ppHead);
// 头插
void SListPushFront(PNode*ppHead,
DataType data);
// 头删
void SListPopFront(PNode* ppHead);
// 在链表中查找元素data,返回该结点在链表中的位置
PNode Find(PNode pHead,
DataType data);
// data插入在pos之前
void SListInsert(PNode* ppHead,
PNode pos,
DataType data);
// 删除链表中pos位置的结点
void SListErase(PNode* ppHead,
PNode pos);
// 获取链表中结点的个数
size_t Size(PNode pHead);
// 判断链表是否为空,若为空,返回true,否则返回false
size_t Empty(PNode pHead);
// 销毁单链表
void SListDestroy(PNode* ppHead);
// 创建结点,并初始化
PNode BuySListNode(DataType data);
// 打印单链表
void SListPrint(PNode pHead);
8d0e
#endif _LINKLIST_H__
1. 链表是一种链式存储的线性表,每个存储单元称为结点
链表是相互连接起来的存储单元,一个存储单元包含两部分
一部分表示的是指向下一个存储单元的指针,另一部分表示的是的存储单元中的数据元素。
2. 接下来就进行一些基本的链表操作
(1)链表的建立
//链表类型在头文件中的定义
typedef int DataType;
typedef struct SListNode
{
DataType _data;
struct SListNode* _pNext;
// 指向下一个结点的指针
}Node, *PNode;
//开辟空间,并初始化
PNode BuySListNode(DataType data)
{
PNode node = (Node*)malloc(sizeof(Node));//开辟一个Node类型的结点的空间
node->_data = data;
node->_pNext = NULL;
return node;
}
// 尾插
void SListPushBack(PNode*ppHead,
DataType data)
{
assert(ppHead);
if (NULL == *ppHead)
{
*ppHead = BuySListNode(data);
}
else
{
PNode pTail = *ppHead;
while (pTail->_pNext)
{
pTail = pTail->_pNext;
}
pTail->_pNext = BuySListNode(data);
}
}
// 头插
void SListPushFront(PNode*
ppHead,
DataType data)
{
assert(ppHead);
PNode pnewnode = BuySListNode(data);//创建一个新的头结点
pnewnode->_pNext = *ppHead;//更新头结点
*ppHead = pnewnode;
}
(2) 链表的特殊位置以及指定位置的插入和删除
// 尾删
void SLis
4000
tPopBack(PNode*
ppHead)
{
assert(ppHead);
PNode pTail = *ppHead;
PNode pre =
NULL;
while (pTail ==
NULL)//为空时,直接返回
{
printf("链表为空");
return;
}
if (pTail->_pNext ==
NULL)//有一个结点时,释放掉一个结点
{
free(pTail);
pTail = NULL;
}
else if (pTail->_pNext)//为多个时,借用pre来更新链表
{
pre = pTail;
pTail->_pNext = pTail;
}
free(pTail);
pre->_pNext = NULL;
}
// 头删
void SListPopFront(PNode*
ppHead)
{
assert(ppHead);
while (*ppHead ==
NULL)
{
printf("链表为空");
return;
}
PNode pdel = *ppHead;//pdel指向头结点
*ppHead = pdel->_pNext;//改变头结点的位置
free(pdel);
}
// data插入在pos之前
void SListInsert(PNode*
ppHead,
PNode pos,
DataType data)// 1 2 3(5) 4-------》pos为4,data为5
{
assert(ppHead);
PNode pcur = *ppHead;
PNode pnewnode = BuySListNode(data);
if (pcur==
pos)//当pos为头结点时
{
SListPushFront(ppHead,
data);//头插
}
if (pcur->_pNext !=
pos)//后移
{
pcur = pcur->_pNext;
}
else
{
pcur->_pNext = pnewnode;//3指向5
pnewnode->_pNext = pos;//5指向4
}
}
// 删除链表中pos位置的结点
void SListErase(PNode*
ppHead,
PNode pos)// 1 2 3 4---->删除pos为3的结点
{
assert(ppHead);
PNode pcur = *ppHead;
PNode pre = *ppHead;
if(pcur==NULL||pos==NULL)
{
printf("无法删除");
}
if (pcur ==
pos)//当pos为头结点时
{
SListPopFront(ppHead);//头删
}
else
{
PNode pre = *ppHead;
while (pre&&pre->_pNext !=
pos)
{
pre = pre->_pNext;
}
if (pre)
{
pre->_pNext = pos->_pNext;//更新链表
}
free(pos);
}
(3)其余的操作
// 在链表中查找元素data,返回该结点在链表中的位置
PNode Find(PNode pHead,
DataType data)
{
assert(pHead);
PNode pcur =
pHead;
while (pcur)
{
if (pcur->_data ==
data)
{
return pcur;
}
pcur = pcur->_pNext;
}
return NULL;
}
// 获取链表中结点的个数
int Size(PNode pHead)
{
PNode pcur = pHead;
assert(pHead);
int count;
while (pcur)
{
count++;
pcur = pcur->p_Next;
}
return count;
}
// 判断链表是否为空,若为空,返回true,否则返回false
size_t Empty(PNode pHead)
{
assert(pHead);
if (pHead ==
NULL)
{
return 1;
}
else
return 0;
}
// 销毁单链表
void SListDestroy(PNode * ppHead)
{
assert(ppHead);
PNode pre = NULL;//用于更新链表
PNode pcur = *ppHead;
while (pcur)
{
pre = pcur;
pcur->_pNext = pcur;
}
free(pcur);
free(pre);
}
// 打印单链表
void SListPrint(PNode pHead)
{
assert(pHead);
PNode pcur = pHead;
while (pcur)
{
printf("->%d", pcur->_data);
}
printf("\n");
}
3. 测试函数
#include "linklist.h"
int main()
{
Node* L=NULL;//L为指向链表的指针
Node *pos = L;//pos为二级指针
pos = pos->_pNext;
BuySListNode(0);
SListPushBack(&L, 1);//需要传指针的地址,因为需要对链表会有内容的改变
SListPushBack(&L, 2);
SListPushBack(&L, 3);
SListPushBack(&L, 4);
SListPushBack(&L, 5);
SListPrint(&L);
SListPopBack(&L);
SListPrint(&L);
SListPushFront(&L, 0);
SListPrint(&L);
SListPopFront(&L);
// 在链表中查找元素data,返回该结点在链表中的位置
Find(&L, 3);
// data插入在pos之前
SListInsert(&L, pos, 8);
SListPrint(&L);
SListErase(&L, pos);
SListPrint(L);
// 获取链表中结点的个数
Size(L);
// 判断链表是否为空,若为空,返回true,否则返回false
Empty(L);
// 销毁单链表
SListDestroy(&L);
system("pause");
return 0;
}
4.头文件
#include"stdio.h"
#include"assert.h"
#include"windows.h"
#ifndef _LINKLIST_H__
#define _LINKLIST_H__
//链表类型在头文件中的定义
typedef int DataType;
typedef struct SListNode
{
DataType _data;
struct SListNode* _pNext;
// 指向下一个结点的指针
}Node, *PNode;
// 尾插
void SListPushBack(PNode*ppHead,
DataType data);
// 尾删
void SListPopBack(PNode* ppHead);
// 头插
void SListPushFront(PNode*ppHead,
DataType data);
// 头删
void SListPopFront(PNode* ppHead);
// 在链表中查找元素data,返回该结点在链表中的位置
PNode Find(PNode pHead,
DataType data);
// data插入在pos之前
void SListInsert(PNode* ppHead,
PNode pos,
DataType data);
// 删除链表中pos位置的结点
void SListErase(PNode* ppHead,
PNode pos);
// 获取链表中结点的个数
size_t Size(PNode pHead);
// 判断链表是否为空,若为空,返回true,否则返回false
size_t Empty(PNode pHead);
// 销毁单链表
void SListDestroy(PNode* ppHead);
// 创建结点,并初始化
PNode BuySListNode(DataType data);
// 打印单链表
void SListPrint(PNode pHead);
8d0e
#endif _LINKLIST_H__
相关文章推荐
- 单链表基本操作以及一些常见的面试问题
- 树的基本结构,以及利用链表实现树的各项操作(创建、添加/删除/打印树节点、销毁等等)
- 双链表以及循环链表的基本操作
- 链表的建立以及各种基本操作
- 单链表以及基本操作-基础
- 动态内存分配以及链表的基本操作
- 链表的java实现以及基本的增加,删除,排序操作
- 浅谈链表以及链表基本操作
- python实现链表基本操作以及链表成对调换
- 单链表的基本操作
- 一道关于链表的基本操作题
- 双向链表的基本操作
- 双向链表的一些基本操作
- 单链表基本操作的简单实现
- 大话数据结构(一)链表的基本操作
- c++实现链表的基本操作
- 链表的基本操作
- GIT代码管理工具安装以及基本操作
- 单链表的基本结构与操作(1)
- 链表的基本操作实现(创建,增,删,逆置)