[置顶] 【c语言】 单链表
2016-05-26 12:25
281 查看
单链表,顾名思义是一种链式存取的数据结构,用一组地址任意的存储单元存放线性表中的数据元素。
链表中的数据是以结点来表示的,每个结点的构成:元素(数据元素的映象) + 指针(指示后继元素存储位置),元素就是存储数据的存储单元,指针就是连接每个结点的地址数据。
我们在这里使用C语言实现:
.h 文件:#pragma once
#include#include typedef int DataType;
typedef struct SListNode
{
DataType data;
struct SListNode* next;
}SListNode;
void PushBack(SListNode* & pHead, DataType x);
void PopBack(SListNode* & pHead);
void PushFront(SListNode* & pHead, DataType x);
void PopFront(SListNode* & pHead);
SListNode* Find(SListNode* pHead, DataType x);
void Insert(SListNode* pos, DataType x);
void Erase(SListNode* pos);
void DestoryList(SListNode*& pHead);
void DestoryList(SListNode*& pHead)
{
SListNode* cur = pHead;
while (cur)
{
SListNode* tmp = cur;
cur = cur->next;
free(tmp);
}
pHead = NULL;
}
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);
}
}
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);
//SListNode* next = pos->next;
//pos->next = tmp;
//tmp->next = next;
SListNode* tmp = _BuyNode(x);
tmp->next = pos->next;
pos->next = tmp;
}
void Erase(SListNode*& pHead, SListNode* pos)
{
assert(pos);
assert(pHead);
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* next = del->next;
pos->data = del->data;
pos->next = next;
free(del);
}
// 在无头单链表的一个非头节点前插入一个节点
void InsertFrontNode(SListNode* pos, DataType x)
{
assert(pos);
//SListNode* tmp = _BuyNode(x);
//tmp->next = pos->next;
//pos->next = tmp;
//DataType tmpData = pos->data;
//pos->data = tmp->data;
//tmp->data = tmpData;
SListNode* tmp = _BuyNode(pos->data);
tmp->next = pos->next;
pos->next = tmp;
pos->data = x;
}
//struct Ret
//{
// SListNode* first;
// SListNode* second;
//};
SListNode* FindMidNode(SListNode* pHead)
{
SListNode* fast = pHead;
SListNode* slow = pHead;
while (fast&&fast->next)
{
slow = slow->next;
fast = fast->next->next;
}
//while (fast)
//{
// if (fast->next)
// {
// fast = fast->next->next;
// }
// else
// {
// break;
// }
// slow = slow->next;
//}
return slow;
}
SListNode* FindKNode(SListNode* pHead, int k)
{
SListNode* fast = pHead;
SListNode* slow = pHead;
while (fast && k--)
{
fast = fast->next;
}
if (k > 0)
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;
}
当一些函数功能写好后,我们必须进行测试,在这里并不是全部写完才进行,
需要进行模块化的测试,这样避免了更多的错误,有问题及时可以发现并解决。
.cpp 文件:
#include #include "SList.h"
// PushBack/PopBack
void Test1()
{
SListNode* list = NULL;
PushBack(list, 1);
PushBack(list, 2);
PushBack(list, 3);
PushBack(list, 4);
PrintSlist(list);
PopBack(list);
PopBack(list);
PopBack(list);
PopBack(list);
PopBack(list);
PrintSlist(list);
}
// PushFront/PopFront
void Test2()
{
SListNode* list = NULL;
PushFront(list, 1);
PushFront(list, 2);
PushFront(list, 3);
PushFront(list, 4);
PrintSlist(list);
PopFront(list);
PopFront(list);
PopFront(list);
PopFront(list);
PopFront(list);
PrintSlist(list);
}
// Find/Insert
void Test3()
{
SListNode* list = NULL;
PushFront(list, 1);
PushFront(list, 2);
PushFront(list, 3);
PushFront(list, 4);
PrintSlist(list);
SListNode* pos = Find(list, 3);
Insert(pos, 10);
pos = Find(list, 1);
Insert(pos, 100);
PrintSlist(list);
// ??
pos = Find(list, 4);
Erase(list, pos);
pos = Find(list, 100);
Erase(list, pos);
pos = Find(list, 3);
Erase(list, pos);
PrintSlist(list);
}
//DelNonTailNode
void Test4()
{
SListNode* list = NULL;
PushBack(list, 1);
PushBack(list, 2);
PushBack(list, 3);
PushBack(list, 4);
PrintSlist(list);
SListNode* pos = list;
DelNonTailNode(pos);
PrintSlist(list);
}
void Test5()
{
SListNode* list = NULL;
PushBack(list, 1);
SListNode* pos = FindMidNode(list);
printf("%d\\\\\\\\n", pos->data);
PushBack(list, 2);
PushBack(list, 3);
PushBack(list, 4);
pos = FindMidNode(list);
printf("%d\\\\\\\\n", pos->data);
pos = FindKNode(list, 4);
pos = FindKNode(list, 100);
}
void Test6()
{
SListNode* list = NULL;
PushBack(list, 1);
PushBack(list, 2);
PushBack(list, 3);
PushBack(list, 4);
//PrintTailToHead(list);
list = Reverse(list);
PrintSlist(list);
//PrintTailToHead(list);
}
void Test7()
{
SListNode* list = NULL;
PushBack(list, 1);
PushBack(list, 2);
PushBack(list, 3);
PushBack(list, 4);
PushBack(list, 5);
PushBack(list, 6);
PushBack(list, 7);
SListNode* tail = Find(list, 7);
tail->next = list;
SListNode* lastOne = JoseCycle(list, 3);
printf("幸存者:%d\\\\\\\\n", lastOne->data);
}
void Test8()
{
SListNode* list = NULL;
PushBack(list, 3);
PushBack(list, 2);
PushBack(list, 3);
PushBack(list, 6);
PushBack(list, 0);
PushBack(list, 9);
PushBack(list, 7);
PrintSlist(list);
BubbleSort(list);
PrintSlist(list);
}
void Test9()
{
SListNode* list1 = NULL, *list2 = NULL;
PushBack(list1, 2);
PushBack(list1, 3);
PushBack(list1, 8);
PrintSlist(list1);
PushBack(list2, 1);
PushBack(list2, 3);
PushBack(list2, 5);
PushBack(list2, 7);
PrintSlist(list2);
SListNode* list = MergeList(list1, list2);
PrintSlist(list);
DestoryList(list);
}
void Test10()
{
SListNode* list = NULL;
PushBack(list, 1);
PushBack(list, 2);
PushBack(list, 3);
PushBack(list, 4);
PushBack(list, 5);
PushBack(list, 6);
PushBack(list, 7);
PrintSlist(list);
SListNode* tail = Find(list, 7);
SListNode* enrtyNode = Find(list, 4);
tail->next = enrtyNode;
SListNode* meetNode = CheckCycle(list);
int length = GetCycleLength(meetNode);
printf("meetNode:%d, length:%d\\\\\\\\n", meetNode->data, length);
SListNode* retEntryNode = GetEntryNode(list);
//assert(retEntryNode == enrtyNode);
}
int main()
{
//Test1();
//Test2();
//Test3();
//Test4();
//Test5();
//Test6();
//Test7();
//Test8();
//Test9();
Test10();
return 0;
}本文出自 “Vs吕小布” 博客,谢绝转载!
链表中的数据是以结点来表示的,每个结点的构成:元素(数据元素的映象) + 指针(指示后继元素存储位置),元素就是存储数据的存储单元,指针就是连接每个结点的地址数据。
我们在这里使用C语言实现:
.h 文件:#pragma once
#include#include typedef int DataType;
typedef struct SListNode
{
DataType data;
struct SListNode* next;
}SListNode;
void PushBack(SListNode* & pHead, DataType x);
void PopBack(SListNode* & pHead);
void PushFront(SListNode* & pHead, DataType x);
void PopFront(SListNode* & pHead);
SListNode* Find(SListNode* pHead, DataType x);
void Insert(SListNode* pos, DataType x);
void Erase(SListNode* pos);
void DestoryList(SListNode*& pHead);
void DestoryList(SListNode*& pHead)
{
SListNode* cur = pHead;
while (cur)
{
SListNode* tmp = cur;
cur = cur->next;
free(tmp);
}
pHead = NULL;
}
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);
}
}
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);
//SListNode* next = pos->next;
//pos->next = tmp;
//tmp->next = next;
SListNode* tmp = _BuyNode(x);
tmp->next = pos->next;
pos->next = tmp;
}
void Erase(SListNode*& pHead, SListNode* pos)
{
assert(pos);
assert(pHead);
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* next = del->next;
pos->data = del->data;
pos->next = next;
free(del);
}
// 在无头单链表的一个非头节点前插入一个节点
void InsertFrontNode(SListNode* pos, DataType x)
{
assert(pos);
//SListNode* tmp = _BuyNode(x);
//tmp->next = pos->next;
//pos->next = tmp;
//DataType tmpData = pos->data;
//pos->data = tmp->data;
//tmp->data = tmpData;
SListNode* tmp = _BuyNode(pos->data);
tmp->next = pos->next;
pos->next = tmp;
pos->data = x;
}
//struct Ret
//{
// SListNode* first;
// SListNode* second;
//};
SListNode* FindMidNode(SListNode* pHead)
{
SListNode* fast = pHead;
SListNode* slow = pHead;
while (fast&&fast->next)
{
slow = slow->next;
fast = fast->next->next;
}
//while (fast)
//{
// if (fast->next)
// {
// fast = fast->next->next;
// }
// else
// {
// break;
// }
// slow = slow->next;
//}
return slow;
}
SListNode* FindKNode(SListNode* pHead, int k)
{
SListNode* fast = pHead;
SListNode* slow = pHead;
while (fast && k--)
{
fast = fast->next;
}
if (k > 0)
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;
}
当一些函数功能写好后,我们必须进行测试,在这里并不是全部写完才进行,
需要进行模块化的测试,这样避免了更多的错误,有问题及时可以发现并解决。
.cpp 文件:
#include #include "SList.h"
// PushBack/PopBack
void Test1()
{
SListNode* list = NULL;
PushBack(list, 1);
PushBack(list, 2);
PushBack(list, 3);
PushBack(list, 4);
PrintSlist(list);
PopBack(list);
PopBack(list);
PopBack(list);
PopBack(list);
PopBack(list);
PrintSlist(list);
}
// PushFront/PopFront
void Test2()
{
SListNode* list = NULL;
PushFront(list, 1);
PushFront(list, 2);
PushFront(list, 3);
PushFront(list, 4);
PrintSlist(list);
PopFront(list);
PopFront(list);
PopFront(list);
PopFront(list);
PopFront(list);
PrintSlist(list);
}
// Find/Insert
void Test3()
{
SListNode* list = NULL;
PushFront(list, 1);
PushFront(list, 2);
PushFront(list, 3);
PushFront(list, 4);
PrintSlist(list);
SListNode* pos = Find(list, 3);
Insert(pos, 10);
pos = Find(list, 1);
Insert(pos, 100);
PrintSlist(list);
// ??
pos = Find(list, 4);
Erase(list, pos);
pos = Find(list, 100);
Erase(list, pos);
pos = Find(list, 3);
Erase(list, pos);
PrintSlist(list);
}
//DelNonTailNode
void Test4()
{
SListNode* list = NULL;
PushBack(list, 1);
PushBack(list, 2);
PushBack(list, 3);
PushBack(list, 4);
PrintSlist(list);
SListNode* pos = list;
DelNonTailNode(pos);
PrintSlist(list);
}
void Test5()
{
SListNode* list = NULL;
PushBack(list, 1);
SListNode* pos = FindMidNode(list);
printf("%d\\\\\\\\n", pos->data);
PushBack(list, 2);
PushBack(list, 3);
PushBack(list, 4);
pos = FindMidNode(list);
printf("%d\\\\\\\\n", pos->data);
pos = FindKNode(list, 4);
pos = FindKNode(list, 100);
}
void Test6()
{
SListNode* list = NULL;
PushBack(list, 1);
PushBack(list, 2);
PushBack(list, 3);
PushBack(list, 4);
//PrintTailToHead(list);
list = Reverse(list);
PrintSlist(list);
//PrintTailToHead(list);
}
void Test7()
{
SListNode* list = NULL;
PushBack(list, 1);
PushBack(list, 2);
PushBack(list, 3);
PushBack(list, 4);
PushBack(list, 5);
PushBack(list, 6);
PushBack(list, 7);
SListNode* tail = Find(list, 7);
tail->next = list;
SListNode* lastOne = JoseCycle(list, 3);
printf("幸存者:%d\\\\\\\\n", lastOne->data);
}
void Test8()
{
SListNode* list = NULL;
PushBack(list, 3);
PushBack(list, 2);
PushBack(list, 3);
PushBack(list, 6);
PushBack(list, 0);
PushBack(list, 9);
PushBack(list, 7);
PrintSlist(list);
BubbleSort(list);
PrintSlist(list);
}
void Test9()
{
SListNode* list1 = NULL, *list2 = NULL;
PushBack(list1, 2);
PushBack(list1, 3);
PushBack(list1, 8);
PrintSlist(list1);
PushBack(list2, 1);
PushBack(list2, 3);
PushBack(list2, 5);
PushBack(list2, 7);
PrintSlist(list2);
SListNode* list = MergeList(list1, list2);
PrintSlist(list);
DestoryList(list);
}
void Test10()
{
SListNode* list = NULL;
PushBack(list, 1);
PushBack(list, 2);
PushBack(list, 3);
PushBack(list, 4);
PushBack(list, 5);
PushBack(list, 6);
PushBack(list, 7);
PrintSlist(list);
SListNode* tail = Find(list, 7);
SListNode* enrtyNode = Find(list, 4);
tail->next = enrtyNode;
SListNode* meetNode = CheckCycle(list);
int length = GetCycleLength(meetNode);
printf("meetNode:%d, length:%d\\\\\\\\n", meetNode->data, length);
SListNode* retEntryNode = GetEntryNode(list);
//assert(retEntryNode == enrtyNode);
}
int main()
{
//Test1();
//Test2();
//Test3();
//Test4();
//Test5();
//Test6();
//Test7();
//Test8();
//Test9();
Test10();
return 0;
}本文出自 “Vs吕小布” 博客,谢绝转载!
相关文章推荐
- [置顶] 【c语言】 单链表
- [置顶] 【C语言】 简易通讯录
- [置顶] 【C语言】 动态开辟二维数组
- [置顶] 【C语言】 使用回调函数实现冒泡排序
- [置顶] 【C语言】 函数指针小谈
- [置顶] 【C语言】 模拟计算器
- [置顶] 【C语言】 浅谈指针
- [置顶] 【C语言】 检测大小端存储
- [置顶] 【C语言】 实现strncpy,strncat,strncmp
- [置顶] 【C语言】 实现memset
- [置顶] 【C语言】 实现memcmp
- [置顶] 【C语言】 实现memmove
- [置顶] 【C语言】 冒泡排序子例
- [置顶] 【C语言】 实现memcpy
- [置顶] 【C语言】 冒泡排序
- [置顶] 【C语言】 实现strcmp
- [置顶] 【C语言】 实现strncat
- [置顶] 【C语言】实现strcat
- [置顶] 【C语言】 实现strcpy
- [置顶] 【C语言】 实现strlen