数据结构与算法系列(1)-单链表类的实现(C++)

通过定义一个C++类封装单链表这种数据结构,

封装的方法有:

1.通过输入创建单链表;

2.获取单链表的数据元素个数;

3.打印输出单链表中各个元素;

4.搜索某个元素在单链表中的位置;

5.在某个位置之后插入一个结点;

6.在某个位置删除一个节点;

7.单链表逆置;

8.单链表是否存在回环的判定;

9.单链表的升序排序;

10.两个单链表的升序合并;

11.两个单链表的降序合并。

注:单链表的排序采用的是快速排序的方法。

下面是C++写的程序代码,附运行截图。

#include <iostream>
#include <malloc.h>
#include <math.h>

using namespace std;

typedef struct node //结点类型
{
	int data;//数据域
	node* next;//指针域
}node;

class LinkList//单链表类的定义
{

public:
	LinkList(int N=0)//但参数构造函数,生成含N个元素的链表(不包括头结点)
	{
		CreateList(N);
		len=GetLength();
	}
	node* head;//头结点指针
	int len;//元素个数
public:
	void CreateList(int n);//根据输入创建单链表
	int GetLength();//获取单链表的长度(元素个数)
	void PrintList();//打印单链表的各个元素
	int  SearchNode(int data);//查找某个元素在单链表中的位置,不过不存在,返回0。
	bool InsertNode(int pos,int data);//在pos位置后插入值为data的节点
	bool DeleteNode(int pos);//删除pos位置后的第一个元素,删除成功返回true.
	void Reverse();//将单链表逆置
	bool IsLoop();//判断单链表中是否存在会换,存在返回真,不存在返回false
	void SelfASOrder();//将链表中元素升序排列
	void ASCMerge(LinkList& L);//与另一个链表升序合并
	void DESCMerge(LinkList& L);//与L链表降序合并

private:
	void QuikSort(node* start,node* end);

};

void LinkList::CreateList(int n)//根据输入创建单链表
{
	head = new node;
	head->data=0;
	head->next=NULL;
	node *p,*q;
	int temp;
	q=head;
	while(n--)
	{
		cin>>temp;
		p=new node;
		p->data=temp;
		p->next=NULL;
		q->next=p;
		q=p;
		p=NULL;

	}
	q=NULL;
	delete q;

}

void LinkList::PrintList()//打印单链表的每一个元素
{
	len=GetLength();
	int l=len;

	node* p=head->next;
	while(l--)
	{
		cout<<p->data<<"  ";
		p=p->next;
	}
	p=NULL;
	delete p;
	cout<<endl;
}

int LinkList::GetLength()//获取单链表的长度
{
	int l=0;
	node* p=head;
	while((p->next)!=NULL)
	{
		l++;
		p=p->next;
	}
	return l;
}

int LinkList::SearchNode(int data)//查找某个元素在单链表中的位置,如果不存在这个元素,返回0
{
	int locate=0;
	node *p=head->next;
	while(len--)
	{
		if(p->data==data)
		{  locate=10-len;
			break;
		}
		p=p->next;
	}
	return locate;
}

bool LinkList::InsertNode(int pos,int data)//插入节点
{
	len=GetLength();
	if(pos>len)//插入位置超出范围
		return false;

	node* p=head->next;
	if(0==pos)
	{
		p=head;
		node* q = new node;
		q->data=data;
		q->next=p->next;
		p->next=q;
		p=NULL;
		q=NULL;
		delete p;
		delete q;
		len++;
		return true;
	}
	else
	{

	pos=pos-1;
	while(pos--)
	{
		p=p->next;
	}
	node* q = new node;
	q->data=data;
	q->next=p->next;
	p->next=q;
	p=NULL;
	q=NULL;
	delete p;
	delete q;
	len++;
	return true;
	}
}

bool LinkList::DeleteNode(int pos)
{
	len=GetLength();
	if(pos>=len)
		return false;
	node* p=head;
	pos=pos-1;
	while(pos--)
	{
		p=p->next;
	}
	node* q=p->next;
	p->next=p->next->next;
	delete q;
	q=NULL;
	len++;
	return true;

}

void LinkList::Reverse()
{
	node *p,*q,*r;
	if(head->next==NULL)
	{
		return;
	}
	p=head->next;
	q=p->next;
	p->next=NULL;
	while(q!=NULL)
	{
		r=q->next;
		q->next=p;
		p=q;
		q=r;
	}
	head->next=p;
}

bool LinkList::IsLoop()
{
	node *p=head->next;
	node* q=head->next->next;
	while((q!=NULL)&&(p!=q))
	{
		p=p->next;
		q=q->next->next;

	}
	if(p==q)
		return true;
	else
		return false;
}

void LinkList::SelfASOrder()//升序排列,采用快速排序的方法
{
	node* start,*end;
	int len=GetLength();
	start=head->next;
	end=start;
	while((end->next)!=NULL)
		end=end->next;
	QuikSort(start,end);

}

void LinkList::QuikSort(node* start,node*end)
{

	if(start==end)
		return;
	int Len=0;
	node* st=start;
	node* en=end;
	while(st!=en)
	{
		st=st->next;
		Len++;
	}
	double x=Len/2.0;
	double xL=floor(x);
	double xU=ceil(x);
	double HalfLen=x;
	int L=xL;
	int U=xU;
	node* mid=start;
	node* midl=start;

	while(U--)
	{
		mid=mid->next;
	}

	while(L--)
	{
		midl=midl->next;
	}
	node* s=start;
	node* m=mid;
	int flag=0;
	for(int i=0;i<xL+1;++i)
	{
		flag=midl-start+1;
		if((s->data)>(m->data))
		{
			s->data^=m->data;//交换
			m->data^=(s->data);
			s->data^=(m->data);
		}
		s=s->next;
		m=m->next;

	}
	QuikSort(start,midl);
	QuikSort(mid,end);
}

void LinkList::ASCMerge(LinkList& L)
{
	this->SelfASOrder();
	L.SelfASOrder();
	node* q=(L.head)->next;
	node* p=head->next;
	int position=0;
	while((p!=NULL)&&(q!=NULL))
	{
		if(q->data<p->data)
		{
			InsertNode(position,q->data);
			q=q->next;
			position++;
		}
		else
		{
			p=p->next;
			position++;
		}
	}
	position=GetLength();
	while(q!=NULL)
	{
		InsertNode(position,q->data);
		q=q->next;
		position++;
	}

}

void LinkList::DESCMerge(LinkList& L)
{
	ASCMerge(L);
	Reverse();
}

int main()
{
	LinkList L(10);
	cout<<"Input the L1 List:"<<endl;
	LinkList L1(15);
	L.PrintList();

	cout<<endl<<"Input the data to search:"<<endl;
	int DataSearch=0;
	cin>>DataSearch;
	cout<<L.SearchNode(DataSearch)<<endl;

	cout<<"Input the data to insert:"<<endl;
	int DataInsert=0;
	cin>>DataInsert;
	cout<<"Input the position to insert:"<<endl;
	int PosInsert=0;
	cin>>PosInsert;
	if(L.InsertNode(PosInsert,DataInsert))
	{
	cout<<"Insert successfully! The new list is:";
	L.PrintList();

	}
	else
	cout<<"Insert Failed!"<<endl;

	cout<<"Input the position to delete:"<<endl;
	int PosDel=0;
	cin>>PosDel;
	if(L.DeleteNode(PosDel))
	{
	cout<<"Delete successfully! The new list is:";
	L.PrintList();
	}
	else
	{
	cout<<"Delete Failed!"<<endl;
	}

	L.Reverse();
	cout<<"The new list after reversed is:";
	L.PrintList();

	/*if(L.IsLoop())
		cout<<"There is a Loop in the List"<<endl;
	else
		cout<<"There is No Loop in the List"<<endl;
*/
	L.SelfASOrder();
	cout<<"List after ASCSorted:";
	L.PrintList();

	LinkList L2;
	L2=L;
	L2.ASCMerge(L1);
	cout<<"L and L1 ASCMerge is:"<<endl;
	L2.PrintList();

	LinkList L3;
	L3=L;
	L3.DESCMerge(L1);
	cout<<"L and L1 DESCMerge is:"<<endl;
	L3.PrintList();

	return 0;
}

运行截图

时间: 2024-10-13 15:52:39

数据结构与算法系列(1)-单链表类的实现(C++)的相关文章

数据结构与算法之PHP实现链表类(单链表/双链表/循环链表)

链表是由一组节点组成的集合.每个节点都使用一个对象的引用指向它的后继.指向另一个节点的引用叫做链. 链表分为单链表.双链表.循环链表. 一.单链表 插入:链表中插入一个节点的效率很高.向链表中插入一个节点,需要修改它前面的节点(前驱),使其指向新加入的节点,而新加入的节点则指向原来前驱指向的节点(见下图). 由上图可知,B.C之间插入D,三者之间的关系为 current为插入节点的前驱节点 current->next = new              // B节点指向新节点D new->n

数据结构和算法基础之单链表

using System; using System.Collections.Generic; using System.Linq; using System.Text; using System.Threading.Tasks; namespace ConsoleApplication1 { public class Node<T> { public T Data; public Node<T> Next; public Node() { Data = default(T); N

数据结构与算法系列四(单链表)

1.引子 1.1.为什么要学习数据结构与算法? 有人说,数据结构与算法,计算机网络,与操作系统都一样,脱离日常开发,除了面试这辈子可能都用不到呀! 有人说,我是做业务开发的,只要熟练API,熟练框架,熟练各种中间件,写的代码不也能“飞”起来吗? 于是问题来了:为什么还要学习数据结构与算法呢? #理由一: 面试的时候,千万不要被数据结构与算法拖了后腿 #理由二: 你真的愿意做一辈子CRUD Boy吗 #理由三: 不想写出开源框架,中间件的工程师,不是好厨子 1.2.如何系统化学习数据结构与算法?

数据结构与算法系列 目录

最近抽空整理了"数据结构和算法"的相关文章.在整理过程中,对于每种数据结构和算法分别给出"C"."C++"和"Java"这三种语言的实现:实现语言虽不同,但原理如出一辙.因此,读者在了解和学习的过程中,择其一即可! 下面是整理数据数据和算法的目录表,对于每一种按照C/C++/Java进行了划分,方便查阅.若文章有错误或纰漏,请不吝指正.谢谢! 数据结构和算法目录表   C C++ Java 线性结构 1. 数组.单链表和双链表

深度解析(一)数据结构与算法系列目录

数据结构与算法系列 目录 最近抽空整理了"数据结构和算法"的相关文章.在整理过程中,对于每种数据结构和算法分别给出"C"."C++"和"Java"这三种语言的实现:实现语言虽不同,但原理如出一辙.因此,读者在了解和学习的过程中,择其一即可! 下面是整理数据数据和算法的目录表,对于每一种按照C/C++/Java进行了划分,方便查阅.若文章有错误或纰漏,请不吝指正.谢谢! 数据结构和算法目录表   C C++ Java 线性结构

数据结构与算法系列七(队列)

1.引子 1.1.为什么要学习数据结构与算法? 有人说,数据结构与算法,计算机网络,与操作系统都一样,脱离日常开发,除了面试这辈子可能都用不到呀! 有人说,我是做业务开发的,只要熟练API,熟练框架,熟练各种中间件,写的代码不也能“飞”起来吗? 于是问题来了:为什么还要学习数据结构与算法呢? #理由一: 面试的时候,千万不要被数据结构与算法拖了后腿 #理由二: 你真的愿意做一辈子CRUD Boy吗 #理由三: 不想写出开源框架,中间件的工程师,不是好厨子 1.2.如何系统化学习数据结构与算法?

数据结构与算法系列十三(选择排序)

1.引子 1.1.为什么要学习数据结构与算法? 有人说,数据结构与算法,计算机网络,与操作系统都一样,脱离日常开发,除了面试这辈子可能都用不到呀! 有人说,我是做业务开发的,只要熟练API,熟练框架,熟练各种中间件,写的代码不也能“飞”起来吗? 于是问题来了:为什么还要学习数据结构与算法呢? #理由一: 面试的时候,千万不要被数据结构与算法拖了后腿 #理由二: 你真的愿意做一辈子CRUD Boy吗 #理由三: 不想写出开源框架,中间件的工程师,不是好厨子 1.2.如何系统化学习数据结构与算法?

009实现一个算法来删除单链表中的一个结点,只给出指向那个结点的指针(keep it up)

呵呵,这个题不能直接删除已知的结点,因为是单链表,不知道前驱,只知道 后继结点,直接删除会使链表断开.不过我们可以删除已知结点的后继结点, 把后继结点的值赋值给已知结点. #include <iostream> struct Node { int data; Node* next; }; bool removeNode(Node* vNode) { if (vNode == NULL || vNode->next == NULL) return false; Node* pNext =

实现一个算法从一个单链表中返回倒数第n个元素(keep it up)

我们维护两个指针, 它们之间的距离为n.然后,我将这两个指针同步地在这个单链表上移动,保持它们的距离 为n不变.那么, 当第二个指针指到空时,第一个指针即为所求. #include <iostream> struct Node { int data; Node* next; }; void initList(Node* vNode) { for (int i=0; i < 20; ++i) { Node* TempNode = new Node; TempNode->data =