C++实现自定义数据类型的单链表

//线性表
//线性表是零个或者多个数据元素的有限序列
//特点:元素间有序、个数有限、类型相同
//线性表分为:顺序表(顺序存储)和链表(链式存储)
//
//链表由一系列的节点组成,每个节点至少包含指针域和数据域
//
//这里,我们规定头结点为0号节点,不带任何数据,且数据域是自定义数据类型Person
#include<iostream>
#include<string>
using namespace std;

//自定义数据类型
class Person{
public:
	string name;
	int age;
	Person(){
		this->age = -1;
		this->name = "NULL";
	}
	Person(string name,int age){
		this->age = age;
		this->name = name;
	}
	//bool operator!=(Person &p){  //重载!=
	//	if(name!=p.name || age!=p.age)
	//		return false;
	//	else
	//		return true;
	//}
};

ostream &operator<<(ostream &cout,Person &p){  //重载输出运算符
	cout<<p.name<<" "<<p.age;
	return cout;
}

//链表节点类
class LinkNode{
public:
	Person data;
	LinkNode *next;
	LinkNode(){
		data.age = -1;
		data.name = "NULL";
	}
};

//链表类
class LinkList{
public:
	LinkNode *head;
	int len;
};

//初始化链表
LinkList *InitLinklist(){
	LinkList *lst = new LinkList;
	lst->len = 0;
	lst->head = new LinkNode;       //注意,头结点一般不带数值
	lst->head->next = nullptr;
	cout<<"初始化成功"<<endl;
	return lst;
}

//指定位置插入,比如要插在2号节点的位置,那么要先找到1号节点
void Insert(LinkList *list,int pos,Person *data){
	if(list==nullptr || data==NULL || (pos<0 || pos>list->len)){
		cout<<"插入失败"<<endl;
		return;
	}
	else{
		//首先需要创建新的节点
		LinkNode *n = new LinkNode;
		n->data.age = data->age;
		n->data.name = data->name;
		n->next = nullptr;
		//辅助指针变量
		LinkNode *tmp = list->head;
		for(int i=0;i<pos;i++){
			tmp = tmp->next;
		}
		//找到待插入位置的前一个节点后,进行相应操作
		n->next = tmp->next;
		tmp->next = n;
		list->len+=1;
		cout<<"插入成功"<<endl;
	}
}

//删除指定位置的节点
void Delete(LinkList *list,int pos){
	if(list == nullptr || pos<0 || pos>=list->len)
		return;
	else{
		//查找待删除节点的前一个节点
		LinkNode *tmp = list->head;
		for(int i=0;i<pos-1;i++){
			tmp = tmp->next;
		}
		//先保存指向待删元素的指针
		LinkNode *tmp2 = tmp->next;
		tmp->next = tmp->next->next;
		delete tmp2;
		list->len-=1;
	}
}

//获得链表长度
int Sizelinklist(LinkList *list){
	if(list==nullptr)
		return 0;
	else
		return list->len;
}

//返回头结点外的第一个节点
LinkNode* Front_node(LinkList *list){
	return list->head->next;
}

//释放链表内存
void FreeLinklist(LinkList *list){
	if(list==nullptr)
		return;
	else{
		LinkNode *tmp =list->head;
		while(tmp!=nullptr){
			LinkNode *tmp2 = tmp;
			tmp = tmp->next;
			delete tmp2;
		}
		delete list;  //勿忘
	}
}

//查找给定元素的位置
int find_linklist(LinkList *list,Person *data){
	if(list==nullptr)
		return -1;
	int idx = 0;
	LinkNode *tmp = list->head;
	while(tmp->data.age!=data->age || tmp->data.name!=data->name){
		if(tmp->next==nullptr)
			return -1;
		else{
			tmp = tmp->next;
			idx+=1;
		}
	}
	return idx;
}

//打印链表节点
void Print_linklist(LinkList *list){
	if(list==nullptr)
		return;
	else{
		LinkNode *tmp = list->head->next;
		while(tmp !=nullptr){
			cout<<tmp->data<<" ";
			tmp = tmp->next;
		}
	}
}

int main(){
	//创建链表
	LinkList *list = InitLinklist();

	//插入数据
	Person p1("jack",18);
	Person p2("davi",20);
	Person p3("tom",29);

	Insert(list,0,&p1);
	Insert(list,0,&p2);
	Insert(list,0,&p3);

	//打印链表节点
	Print_linklist(list);
	cout<<endl;
	//打印链表长度
	cout<<Sizelinklist(list)<<endl;
	//查找给定元素的位置
	find_linklist(list,&p1);
	//删除链表节点
	Delete(list,1);
	Print_linklist(list);
	cout<<endl;

	//返回头结点外的第一个节点
	LinkNode *first = Front_node(list);
	cout<<first->data.name<<" "<<first->data.age<<endl;

	return 0;
}




猜你喜欢

转载自blog.csdn.net/qq_43438974/article/details/129361100