[c语言]单链表的实现

原创 2016年06月01日 00:05:27

一、基础知识:链表(线性表的链式存储结构)

(1)特点:逻辑关系相邻,物理位置不一定相邻。

(2)分类:

     a.不带头节点

    b.带头节点

           wKiom1cd_6ijVRHJAAAaP1x2gqE446.png

(3)单链表的存储结构:

typedef struct SListNode

{

 DataType data;

 struct SListNode* next;

}SListNode;

 

二、代码实现(因避开使用二级指针,所以代码中使用了c++中的引用):此处构造的为不带头节点的链表

方法一:

(1)sList.h

 
#pragma once
typedef int DataType;
typedef struct SListNode
{
 DataType data;
 struct SListNode* next;
}SListNode;
void PushBack(SListNode* & pHead, DataType d);
void PopBack(SListNode* & pHead);
void PushFront(SListNode* & pHead, DataType d);
void PopFront(SListNode* & pHead);
void PrintList(SListNode* pHead);
SListNode* Find(SListNode* & pHead, DataType d);
void Insert(SListNode* & pos, DataType d);

(2)sList.cpp

#include <stdio.h>
#include <malloc.h>
#include <assert.h>
#include "sList.h"
SListNode* MakeNode(DataType d)
{
 SListNode* tmp = (SListNode*)malloc(sizeof(SListNode));
 tmp->data = d;
 tmp->next = NULL;
 return tmp;
}
void PushBack(SListNode* & pHead, DataType d)
{
 //1.空
 //2.不空
 if(pHead == NULL)
 {
  pHead = MakeNode(d);
 }
 else
 {
  //先找尾,再插入新节点
  SListNode* tail = pHead;
  while(tail->next != NULL)
  {
   tail = tail->next;
  }
  tail->next = MakeNode(d);
 }
}
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 != NULL)
  {
   prev = tail;
   tail = tail->next;
  }
  prev->next = NULL;
  free(tail);
 }
}
void PushFront(SListNode* & pHead, DataType d)
{
 if(pHead == NULL)
 {
  pHead = MakeNode(d);
 }
 else
 {
  SListNode* tmp = pHead;
  pHead = MakeNode(d);
  pHead->next = tmp;
 }
}
void PopFront(SListNode* & pHead)
{
 if(!pHead)
 {
  printf("List is empty!");
  return;
 }
 else
 {
  SListNode* tmp = pHead;
  pHead = pHead->next;
  free(tmp);
 }
}
SListNode* Find(SListNode* & pHead, DataType d)
{
 SListNode* find = pHead;
 while(find)
 {
  if(find->data == d)
   return find;
  find = find->next;
 }
 return NULL;
}
void Insert(SListNode* & pos, DataType d)
{
 assert(pos);
 /*
 方法一:
 SListNode* tmp = MakeNode(d);
 tmp->next = pos->next;
 pos->next = tmp;
 */
 //方法二:
 SListNode* next = pos->next;
 pos->next = MakeNode(d);
 pos->next->next = next;
}
void Erase(SListNode*& pHead,SListNode* & pos)
{
 assert(pos&&pHead);
 SListNode* prev = pHead;
 while(prev->next != pos)
 {
  prev = prev->next;
 }
 prev->next = pos->next;
 free(pos);
 pos = NULL;
}
void PrintList(SListNode* pHead)
{
 SListNode* tmp = pHead;
 while(tmp)
 {
  printf("%d->", tmp->data);
  tmp = tmp->next;
 }
 printf("NULL\n");

(3)test.cpp

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

void test1()
{
 //不带头节点
 SListNode* list = NULL;
 PushBack(list, 1);
 PushBack(list, 2);
 PushBack(list, 3);
 PushBack(list, 4);
// PushFront(list,0);
// PopFront(list);
// PopBack(list);
 SListNode* ret = Find(list, 2);
 if(ret == NULL)
 {
  printf("No Exist!\n");
  return;
 }
// Insert(ret, 4);
 Erase(list,ret);
 PrintList(list);
}
int main()
{
 test1();
 system("pause");
 return 0;

 方法二:

这种方法定义了两个结构体,方便以后对链表的操作,你可以在LinkList这个结构体中加入尾指针或者长度等等信息,来使操作更加简单。

typedef struct ListNode    //单链表的一个结点
{
	DataType data;
	struct ListNode* next;
}ListNode,*pListNode;
 
typedef struct LinkList   //链表的信息                                                                                            {
	pListNode pHead;
}LinkList,*pLinkList;

 

源文件:

1.LinkList.h

#ifndef __LINKLIST_H__
#define __LINKLIST_H__

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

typedef int DataType;
typedef struct ListNode
{
	DataType data;
	struct ListNode* next;
}ListNode,*pListNode;

typedef struct LinkList
{
	pListNode pHead;
}LinkList,*pLinkList;

void InitLinkList(pLinkList plist);
void DestoryLinkList(pLinkList plist);
void PushBack(pLinkList plist, DataType x);
void PopBack(pLinkList plist);
void PushFront(pLinkList plist, DataType x);
void PopFront(pLinkList plist);
void PrintLinkList(pLinkList plist);
pListNode Find(pLinkList plist, DataType x);
void Insert(pLinkList plist, pListNode pos, DataType x);
void Remove(pLinkList plist, DataType x);
void RemoveAll(pLinkList plist, DataType x);
void Erase(pLinkList plist, pListNode pos);
void BubbleSort(pLinkList plist);

#endif


 

2.LinkList.c

#include "LinkList.h"

void InitLinkList(pLinkList plist)
{
	assert(plist);
	plist->pHead = NULL;
}
void DestoryLinkList(pLinkList plist)
{
	pListNode cur = NULL;
	assert(plist);
	cur = plist->pHead;
	while(cur)
	{
		pListNode del = cur;
		cur = cur->next;
		free(del);
		del = NULL;
	}
	plist->pHead = NULL;
}

pListNode BuyNode(DataType x) //创建一个结点
{
	pListNode newNode = (pListNode)malloc(sizeof(ListNode));
	if(NULL == newNode)
	{
		printf("out of memory!");
		exit(0);
	}
	newNode->data = x;
	newNode->next = NULL;
	return newNode;
}
void PushBack(pLinkList plist, DataType x)
{
	pListNode cur = NULL;
	pListNode newNode = NULL;
	assert(plist);
	cur = plist->pHead;
	newNode = BuyNode(x);
	if(NULL == cur)   //空链表
	{
		plist->pHead = newNode;
	}
	else              //链表不为空
	{
		while(cur->next != NULL)
		{
			cur = cur->next;
		}
		cur->next = newNode;
	}
}
void PopBack(pLinkList plist)
{
	pListNode cur = NULL;
	assert(plist);
	cur = plist->pHead;
	if(NULL == cur)    //链表为空
	{
		printf("LinkList is Empty\n");
	}
	else if(NULL == cur->next) //链表只有一个结点
	{
		free(cur);
		cur = NULL;
		plist->pHead = NULL;
	}
	else    //链表有两个及以上结点
	{
		while(cur->next->next != NULL)
		{
			cur = cur->next;
		}
		free(cur->next);
		cur->next = NULL;
	}
}
void PushFront(pLinkList plist, DataType x)
{
	pListNode newNode = NULL;
	assert(plist);
	newNode = BuyNode(x);
	newNode->next = plist->pHead;
	plist->pHead = newNode;
}
void PopFront(pLinkList plist)
{
	assert(plist);
	if(NULL == plist->pHead)
	{
		printf("LinkList is Empty\n");
		return;
	}
	else
	{
		pListNode del = plist->pHead;
		plist->pHead = del->next;
		free(del);
		del = NULL;
	}
}
void PrintLinkList(pLinkList plist)
{
	pListNode cur = NULL;
	assert(plist);
	cur = plist->pHead;
	while(cur)
	{
		printf("%d->", cur->data);
		cur = cur->next;
	}
	printf("NULL\n");
}
pListNode Find(pLinkList plist, DataType x)
{
	pListNode cur = NULL;
	assert(plist);
	cur = plist->pHead;
	while(cur)
	{
		if(cur->data == x)
		{
			return cur;
		}
		cur = cur->next;
	}
	return NULL;
}
void Insert(pLinkList plist, pListNode pos, DataType x) //在pos之前插入
{
	pListNode newNode = NULL;
	assert(plist);
	assert(pos);
	newNode = BuyNode(x);
	if(pos == plist->pHead)
	{
		PushFront(plist, x);
	}
	else
	{
		pListNode cur = plist->pHead;
		while(cur->next != pos)
		{
			cur = cur->next;
		}
		cur->next = newNode;
		newNode->next = pos;
	}
}
void Remove(pLinkList plist, DataType x)  //删除数据为x的结点
{
	pListNode pos = NULL;
	assert(plist);
	pos = Find(plist, x);
	if(pos == NULL)
	{
		printf("no find\n");
	}
	else if(pos == plist->pHead)
	{
		PopFront(plist);
	}
	else
	{
		pListNode cur = plist->pHead;
		while(cur->next != pos)
		{
			cur = cur->next;
		}
		cur->next = pos->next;
		free(pos);
		pos = NULL;
	}
}
void RemoveAll(pLinkList plist, DataType x)
{
	pListNode cur = NULL;
	assert(plist);
	cur = plist->pHead;
	if(plist->pHead == NULL)//空链表
	{
		return;
	}
	else if(plist->pHead->next == NULL)  //只有一个结点
	{
		free(cur);
		cur = NULL;
		plist->pHead =NULL;
		return;
	}
	while(cur->data == x)  //头
	{
		pListNode del = cur;
		cur = cur->next;
		plist->pHead = cur;
		free(del);
		del = NULL;
	}
	while(cur && cur->next)                  //中间和尾
	{
		if(cur->next->data == x)
		{
			
			pListNode del = cur->next;
			cur->next = del->next;
			free(del);
			del = NULL;
		}
		cur = cur->next;
	}
}
void Erase(pLinkList plist, pListNode pos)
{

	assert(pos);
	assert(plist);
	if(pos == plist->pHead)
	{
		PopFront(plist);
	}
	else
	{
		pListNode cur = plist->pHead;
		while(cur->next != pos)
		{
			cur = cur->next;
		}
		cur->next = pos->next;
		free(pos);
		pos = NULL;
	}
}
void BubbleSort(pLinkList plist)
{
	int flag = 0;
	pListNode cur = NULL;   //控制外循环排序的趟数
	pListNode log= NULL;   //记录内循环上一次交换的最后一个数
	pListNode cmp = NULL;  //记录内循环的当前比较值
	assert(plist);
	log = plist->pHead;
	cur = plist->pHead;

	while(log)
	{
		log = log->next;
	}
	while(cur->next != NULL)
	{
		pListNode node = NULL;
		cmp = plist->pHead;
		log = node;
		flag = 0;
		while(cmp->next!=log)
		{
			if(cmp->data > cmp->next->data)
			{
				DataType tmp = cmp->data;
				cmp->data = cmp->next->data;
				cmp->next->data = tmp;
				node = cmp;
				flag = 1;
			}
			cmp = cmp->next;
		}
		if(flag == 0)
		{
			return;
		}
		cur = cur->next;
	}
}


 

3.Test.c

#include "LinkList.h"

void Test1()
{
	LinkList list;
	InitLinkList(&list);
	PushBack(&list, 1);
	PushBack(&list, 2);
	PushBack(&list, 3);
	PushBack(&list, 4);
	PushBack(&list, 5);
	PrintLinkList(&list);
	PopBack(&list);
	PrintLinkList(&list);
	PopBack(&list);
	PopBack(&list);
	PopBack(&list);
	PopBack(&list);
	PopBack(&list);

	PrintLinkList(&list);
	DestoryLinkList(&list);
}
void Test2()
{
	LinkList list;
	InitLinkList(&list);
	PushFront(&list, 1);
	PushFront(&list, 2);
	PushFront(&list, 3);
	PushFront(&list, 4);
	PushFront(&list, 5);
	PrintLinkList(&list);

	PopFront(&list);
	PrintLinkList(&list);
	PopFront(&list);
	PrintLinkList(&list);
	PopFront(&list);
	PrintLinkList(&list);
	PopFront(&list);
	PrintLinkList(&list);
	PopFront(&list);
	PrintLinkList(&list);
	PopFront(&list);
	PrintLinkList(&list);

	DestoryLinkList(&list);
}

void Test3()
{
	LinkList list;
	InitLinkList(&list);
	PushBack(&list, 1);
	PushBack(&list, 2);
	PushBack(&list, 3);
	PushBack(&list, 4);
	PushBack(&list, 5);
	PrintLinkList(&list);
//	Insert(&list, Find(&list, 4), 3);
	Insert(&list, Find(&list, 1), 3);
	Insert(&list, Find(&list, 5), 3);

	PrintLinkList(&list);
	DestoryLinkList(&list);

}

void Test4()
{
	LinkList list;
	InitLinkList(&list);
	PushBack(&list, 4);
	PushBack(&list, 1);
	PushBack(&list, 2);
	PushBack(&list, 3);
	PushBack(&list, 4);
	PushBack(&list, 5);
	PushBack(&list, 4);
	PrintLinkList(&list);
//	Remove(&list, 1);
//	Remove(&list, 5);
//	Remove(&list, 3);
	RemoveAll(&list, 4);
	PrintLinkList(&list);
	DestoryLinkList(&list);
}

void Test5()
{
	LinkList list;
	InitLinkList(&list);
	PushBack(&list, 4);
	PushBack(&list, 1);
	PushBack(&list, 2);
	PushBack(&list, 3);
	PushBack(&list, 4);
	PushBack(&list, 5);
	PushBack(&list, 4);
	PrintLinkList(&list);
	Erase(&list,Find(&list,3));
	PrintLinkList(&list);
	BubbleSort(&list);
	PrintLinkList(&list);

	DestoryLinkList(&list);
}
int main()
{
//	Test1();
//	Test2();
//	Test3();
//	Test4();
	Test5();

	system("pause");
	return 0;
}


 

版权声明:本文为博主原创文章,未经博主允许不得转载。

C语言单向链表的表示与实现实例详解

C语言单向链表的表示与实现实例详解
  • Rank_d
  • Rank_d
  • 2016年11月02日 19:04
  • 525

C语言单向链表的实现

一个简单结点的结构体表示为:    struct note    {       int  data;              /*数据成员可以是多个不同类型的数据*/       struct  ...
  • 21aspnet
  • 21aspnet
  • 2004年10月30日 16:30
  • 24088

C语言实现链表之单向链表(十五)测试用例

C语言实现链表之单向链表(十五)测试用例     上一篇文章给出了最后的两个函数,即链表打印和排序,这篇文章将给出所有函数的测试用例,即ListTestTop.c文件。 /* ********...
  • dan15188387481
  • dan15188387481
  • 2015年11月08日 21:54
  • 902

单链表的基本操作c语言实现

#include #define false 0 #define ok 1//定义节点的结构 typedef struct node{ int data; struct node *n...
  • gongdileidechouzhu
  • gongdileidechouzhu
  • 2017年02月25日 16:14
  • 826

单链表的基本操作大全之C语言实现(一)

单链表的基本操作大全之C语言实现1. 单链表的定义链表是通过一组任意的存储单元来存储线性表中的数据元素,这些存储单元可以是连续的也可以是不连续的。为了建立起数据元素之间的关系,对于每个数据元素除了存放...
  • men_wen
  • men_wen
  • 2016年10月20日 21:43
  • 8205

C语言-------实现一个简单的单向链表

编写一个链表程序,在程序中实现简单的功能#include #include struct node{ int num; char name[20]; struct node*...
  • zer1123
  • zer1123
  • 2017年02月09日 20:12
  • 2459

C语言实现单链表的逆序打印(带头结点)

我在之前一篇博客《C语言实现单链表(不带头结点)的逆序打印》中详细实现了对一个不带头节点的链表的逆序打印,整体思路也是非常的简单,也就是依次遍历原链表,然后把取出的节点用头插法建立一个新的链表,新链表...
  • CHENYUFENG1991
  • CHENYUFENG1991
  • 2016年03月01日 20:07
  • 3465

数据结构--单链表的基本操作(C语言实现)

数据结构--单链表的基本操作(C语言实现)     #include #include #define ERROR 0 #define OK   1...
  • qq_33609401
  • qq_33609401
  • 2016年09月27日 17:30
  • 1269

数据结构中单链表的实现+单链表的C语言实现源代码

线性表(List):零个或多个数据元素的有限序列。线性表的抽象数据类型。 线性表的顺序存储: 优点:无须为表示表中元素的逻辑关系而额外的存储空间,可以快速的取表中任意位置的元素。 缺点:插入和删...
  • zhuimengfuyun
  • zhuimengfuyun
  • 2013年07月27日 15:25
  • 3156

C语言实现单链表(带头结点)的基本操作

我在之前一篇博客《C语言实现单链表(不带头结点)的基本操作》中具体实现了不带头结点的单链表的11种操作:如计算链表长度、初始化、创建链表、清空链表等等。但是在实际使用中,带头结点的单链表往往比不带头结...
  • CHENYUFENG1991
  • CHENYUFENG1991
  • 2016年03月01日 13:40
  • 5532
内容举报
返回顶部
收藏助手
不良信息举报
您举报文章:[c语言]单链表的实现
举报原因:
原因补充:

(最多只允许输入30个字)