单链表的实现C++封装

本文介绍了单链表这一重要数据结构,并通过C语言详细阐述了算法,包括头插法和尾插法生成单链表。最后,文章提供了完整的C++封装实现。

链表一种重要的数据结构,以下给出单链表的算法,用C语言说明算法,最后给出完整的C++封装。

C语言说明算法

定义单链表节点结构体

struct Node
{
	//数据
	int date;
	//指向下一节点的指针
	struct Node * next;
};


下面是单链表的两种生成方法,头插法产生的单链表,数据存储顺序与数据输入的顺序刚好相反,尾插法数据存储顺序与头插法的相反,即为数据输入的顺序。

头插法生成单链表

//头插法插入元素后得到的链表中元素逆序
void CreateListF(Node *&L, int a[], int n){
	Node *s;
	int i;
	L = (Node *)malloc(sizeof(Node));//申请一块内存空间
	L->next = NULL;//头结点
	for (i = 0; i < n; i++){
		s = (Node *)malloc(sizeof(Node));
		s->date = a[i];
		s->next = L->next;//将L中存放的下一个节点的地址赋给S->next
		L->next = s;//使L指向s本身
	}
}

尾插法生成顺序表

void CreateListB(Node *&L, int a[], int n){
	Node *r, *s;
	int i;
	L = (Node*)malloc(sizeof(Node));
	r = L;//将头结点作为尾节点
	for (i = 0; i < n; i++){
		s = (Node*)malloc(sizeof(Node));//每次都需重新申请空间(每次结束前都会将s申请的空间赋给r)
		s->date = a[i];
		r->next = s;//使r中地址域存储s节点的地址
		r = s;//将s节点的地址赋给r(s所申请的空间给了r,隐含的将数据赋给了r)//地址运算效率更高
	}
	r->next = NULL;//插入完毕后尾节点地址域赋值为空
}

删除链表

//删除链表
void DestroyList(Node *&L){
	Node *pre = L, *p = L->next;
	while (p != NULL){
		free(pre);
		pre = p;//pre得到下一个节点的地址
		p = pre->next;//p指向下下个节点的地址(此时pre以为下一个即将释放的节点的地址)
	}
	free(pre);//最后判断为空时,退出循环释放最后一个节点空间
}


判断是否为空

//判断链表是否为空
bool ListEmpty(Node *&L){
	return (L->next == NULL);
}


链表长度
//链表长度

int ListLength(Node *&L){
	int count = 0;//计数器
	Node *p = L;
	while (p->next != NULL){//当不为空时便+1,直至退出循环
		count++;
		p = p->next;
	}
	return count;
}

输出单链表

//输出单链表
void DisplayList(Node *&L){
	Node *p = L->next;//用于遍历单链表的指针
	while (p != NULL){//遍历输出
		cout << p->date << ends;
		p = p->next;
	}
	cout << endl;
}

按位置查找,并返回值

//查找单链表中的某个值(按位置查找)
bool getElem(Node *&L, int i,int &res){//i为需查找的元素的位置,res用于返回值
	int j = 0;//j用于记录找到的第一个位置
	Node *p = L;
	while (j < i&&p != NULL){
		j++;
		p = p->next;
	}
	//对退出的两种情况做讨论
	if (p == NULL){
		return false;
	}
	else{
		res = p->date;
		return true;
	}
}

按值查找,并返回元素位置

//查找值(按值查找)
int LocateList(Node *&L, int e){
	int i = 0;//i用于记录位置
	Node *p = L;
	while (p != NULL&&p->date != e){
		p = p->next;
		i++;
	}
	//讨论退出的两种情况
	//若p为空则返回0
	if (p == NULL){
		return 0;
	}
	//若找到则返回i
	else{
		return i;
	}
}

在位置i插入元素elem

//在第i个位置插入节点
void InsertNode(Node *&L, int i,int elem){
	i--;//只需找到插入位置i的前一个节点
	Node *p = L, *s;
	int j = 0;
	while (i!=j&&p->next != NULL){
		j++;
		p = p->next;
	}
	//讨论退出循环的两种情况
	if (p->next == NULL){
		cout << "It is empty,error number." << endl;
	}
	//找到位置,插入元素
	else{
		s = (Node *)malloc(sizeof(Node));
		s->date = elem;
		s->next = p->next;
		p->next = s;
	}
}

删除位置i的节点

//删除第i个位置的节点
void DeleteNode(Node *&L, int i){
	i--;
	Node *p = L, *s;
	int j = 0;
	while (i != j&&p->next != NULL){
		j++;
		p = p->next;
	}
	if (p->next == NULL){
		cout << "It is empty,error number." << endl;
	}
	else{
		s = p->next;
		p->next = p->next->next;//跳过需删除的节点
		free(s);//释放需删除的节点的空间
	}
}

以上便是所有单链表C语言的实现,下面给出C++封装好的单链表,其中头插法和尾插法都能用,代码中使用了尾插法。

/*
*单链表的实现
*/
#include<iostream>
using namespace std;
const int MAX_N = 100;
typedef class Node
{
public:
	int data;
	class Node *next;
}ListNode;
class List
{
public:
	//构建单链表并初始化(头插法)
/*	List(int a[], int n){
		ListNode *s;
		int i;
		L = (ListNode *)malloc(sizeof(ListNode));
		L->next = NULL;
		for (i = 0; i < n; i++){
			s = (ListNode *)malloc(sizeof(ListNode));
			s->data = a[i];
			s->next = L->next;
			L->next = s;
		}
	}*/
	//构建并初始化(尾插法)
	List(int a[], int n){
		ListNode *p, *s;
		int i;
		L = (ListNode *)malloc(sizeof(ListNode));
		p = L;
		for (i = 0; i < n; i++){
			s = (ListNode *)malloc(sizeof(ListNode));
			s->data = a[i];
			p->next = s;
			p = s;
		}
		p->next = NULL;
	}
	//析构,释放空间
	~List(){
		ListNode *pre = L, *p = L->next;
		while (p->next != NULL){
			free(pre);
			pre = p;
			p = pre->next;
		}
		free(pre);
	}
	//判断是否为空
	bool isEmpty(){
		return (L->next == NULL);
	}
	//单链表长度
	int getLength(){
		ListNode *p = L;
		int i = 0;
		while (p->next != NULL){
			i++;
			p = p->next;
		}
		return i;
	}
	//输出单链表中元素
	void DisplayList(){
		ListNode *p = L->next;//指向第一个存有数据的节点(非头结点)
		while (p != NULL){
			cout << p->data << ends;
			p = p->next;
		}
		cout << endl;
	}
	//按序号查找并返回数据值
	bool getElem(int i,int &res){
		ListNode *p = L;
		int j = 0;
		while (j != i&&p->next != NULL){
			j++;
			p = p->next;
		}
		if (j!=i&&p->next == NULL){//必须还有j!=i,否则最后一个节点无法访问
			return false;
		}
		else{
			res = p->data;
			return true;
		}
	}
	//按值查找并返回序号
	int LocateElem(int &elem){
		ListNode *p = L;
		int i = 0;
		while (p->data != elem&&p->next != NULL){
			i++;
			p = p->next;
		}
		if (p->data!=elem&&p->next == NULL){
			return 0;
		}
		else{
			return i;
		}
	}
	//插入元素
	void InsertElem(int i, int &elem){
		i--;
		ListNode *p = L, *s;
		int j = 0;
		while (j != i&&p->next != NULL){
			j++;
			p = p->next;
		}
		if (p->next == NULL){
			cout << "error number." << endl;
		}
		else{
			s = (ListNode *)malloc(sizeof(ListNode));
			s->data = elem;
			s->next = p->next;
			p->next = s;
		}
	}
	//删除元素
	bool DeleteElem(int i,int &res){
		i--;
		ListNode *p = L, *s;
		int j = 0;
		while (j != i&&p->next != NULL){
			j++;
			p = p->next;
		}
		if (p->next == NULL){
			return false;
		}
		else{
			s = p->next;
		/*	if (s->next == NULL)
				return false;*/
			res = s->data;
			p->next = p->next->next;
			free(s);
			return true;
		}
	}
private:
	Node *L;
	//返回头结点地址
};
int main()
{
	//ListNode *m_node;
	int n, res=0, a[MAX_N], i;
	cout << "Input the length:" << ends;
	cin >> n;
	for (i = 0; i < n; i++){
		cin >> a[i];
	}
	//创建单链表
	List m_list(a, n);
	//输出
	m_list.DisplayList();
	//判断空,非空返回长度
	if (!m_list.isEmpty()){
		cout << "it is not empty." << endl;
		cout << "The length:" << m_list.getLength() << endl;
	}
	else{
		cout << "It is empty." << endl;
	}
	//按序号查找并返回元素
	cout << "Input number:" << ends;
	cin >> i;
	if (m_list.getElem(i,res)){
		cout << "NO. " << i << " ,data is " << res << endl;
	}
	else{
		cout << "error number or not contained." << endl;
	}
	//按值查找并返回序号
	cout << "Input the data:" << ends;
	cin >> res;
	if (m_list.LocateElem(res) == 0){
		cout << "Not contained." << endl;
	}
	else{
		cout << "The location is No. " << m_list.LocateElem(res) << endl;
	}
	//插入元素
	cout << "Input the number and data:" << ends;
	cin >> i >> res;
	m_list.InsertElem(i, res);
	m_list.DisplayList();
	//删除元素
	cout << "Input number:" << ends;
	cin >> i;
	if (m_list.DeleteElem(i, res)){
		cout << "The NO. " << i << " ,data: " << res << " is deleted." << endl;
		m_list.DisplayList();
	}
	else{
		cout << "Not contain this number." << endl;
	}
	return 0;
}

测试运行



评论 4
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值