链表(包含switch语句需要注意的要点)

#pragma once
#include<iostream>
class Node
{
	private:
		int info;
		Node* link;
public:
	Node(int n=0,Node*p=NULL):info(n),link(p){}
	friend class List;
};


#pragma once
#include"Node.h"
class List
{
private:
	Node* head;
public:
	List(int n = 0);//构造
	void PrintList(); //遍历链表,进行打印
	Node* Find(int data);
	Node* CreatNode(int data); //创建一个结点(孤立结点)
	void InsertOrder(Node* p); //按升序插入生成链表
	void Insert(int n); //按位置插入生成链表(无序)
	~List(); //析构函数,删除所有结点
	void DeleteNode(Node* p); //删除指定结点
	void MakeEmpty(); //清空一个链表,只余表头结点,包含在析构函数当中
};


#include "List.h"
#include"Node.h"
#include<iostream>
using namespace std;
List::List(int n)
{
	head = new Node(n);
}
void List::PrintList()
{
	Node* tempP = head->link;
	cout << head->info << " Nodes: ";
	while (tempP != NULL) {
		cout << tempP->info << '\t';//\t的意思:补全当前字符串长度到8位
		tempP = tempP->link;
	}
	cout << endl;
}
Node* List::Find(int data)
{
	Node* tempP = head->link;
	while (tempP != NULL && tempP->info != data)
		tempP = tempP->link;
	return tempP;
	//搜索成功返回该结点地址,不成功返回NULL
}
Node* List::CreatNode(int data)
{ //建立新节点
	Node* P = new Node(data);
	return P;
}
void List::InsertOrder(Node* p)
{
	Node* tempP = head->link, * tempQ = head;
	//tempQ指向tempP前面的一个节点
	while (tempP != NULL) {
		if (p->info < tempP->info) break;
		//找第一个比插入结点大的结点,由tempP指向
		tempQ = tempP;
		tempP = tempP->link;
	}
	p->link = tempP; //插入节点
	tempQ->link = p;
	head->info++; //头节点记录节点个数
}
void List::Insert(int n) //根据位置插入
{
	if (head->info < n || n < 0)
	{
		cout << "插入位置有误!" << endl;
		return;
	}
	Node* tempP = head; //从head开始数位置
	for (int i = 0; i < n; i++)
		tempP = tempP->link; //指针定位在插入节点前一个节点
	cout << "输入插入节点的数据:";
	int value;
	cin >> value;
	Node* p = new Node(value); //新建将插入节点
	p->link = tempP->link; //插入
	tempP->link = p;
	head->info++; //头节点值域记录链表的个数
} 
void List::DeleteNode(Node* p)
{
	Node* tempP = head->link, * tempQ = head;
	while (tempP != NULL && tempP != p)
	{
		tempQ = tempP;
		tempP = tempP->link;
	}
	if (tempP) {
		tempQ->link = tempP->link;
		delete p;
		head->info--;
	}
}
void List::MakeEmpty()
{
	Node* tempP;
	while (head->link != NULL)
	{
		tempP = head->link;
		head->link = tempP->link;
		//把头结点后的第一个节点从链中脱离
		delete tempP; //删除(释放)脱离下来的结点
		head->info--; //节点个数减少
	}
}
List::~List()
{
	MakeEmpty();
	delete head;
}

/*system("cls");清空之前的结果*/
#include "List.h"
#include "Node.h"
#include <iostream>
using namespace std;
int main() {
	List pl;//创建空链表;
	int num;
	int n1, n2;
	Node* p;
	char option;
	while (1)
	{
		cout << "\n链表操作练习:" << endl;
		cout << "1: 链表中插入新节点(无序)" << endl;
	    cout << "2 : 链表中插入新节点(有序)" << endl;
		cout << "3: 删除节点(值)" << endl;
		cout << "4: 查找节点" << endl;
		cout << "5: 遍历节点" << endl;
		cout << "6: 清空链表" << endl;
		cout << "0: 退出" << endl;
		cout << "\n请输入你的选择:";
		cin >> option	;
		switch (option) {
		case '0':
			break;
		case '1':
			system("cls");//清空之前的结果
			cout << "请输入插入节点的个数:";
			cin >> n1;
			while (n1) {
				cout << "请输入插入节点的位置:";
				cin >> n2;
				pl.Insert(n2);
				n1--;
			}
			pl.PrintList();
			break;
		case '2':
			system("cls");
			cout << "请输入插入的值:"; cin >> num;
			p = pl.CreatNode(num);
			pl.InsertOrder(p);
			pl.PrintList();
			break;
		case '3':
			system("cls");
			cout << "请输入被删除节点值:"; cin >> num;
			p = pl.Find(num);
			pl.DeleteNode(p);
			pl.PrintList();
			break;
		case '4':
			system("cls");
			cout << "请输入要查找的节点的值:"; cin >> num;
			p = pl.Find(num);
			if (p == NULL) cout << "查找失败!" << endl;
			else cout << "查找成功!" << endl;
			break; 
		case '5':
			system("cls");
			cout << "遍历链表所有数据:" << endl
				;
			pl.PrintList();
			break;
		case '6':
			system("cls");
			cout << "清空链表,只留下头节点!" << endl
				;
			pl.MakeEmpty();
			pl.PrintList();
			break;
		default:
			system("cls");
			cout << "你输入错误,请重新输入!" << endl
				;
		}
		if (option == '0')
			break;
	}
}

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

链表编辑学生类

method
1 改成模板类
2 typedef 修改类型名字

#pragma once
#include <iostream>
using namespace std;
class student
{
	//student类型的设计”student.h”
	int id;
	int score;
public:
	student(int i = 0, int s = 0) :id(i), score(s) { }
	operator int() //类型转换函数,用于头节点的节点个数存储
	{
		return score;
	}
	student operator++(int) //头节点中存储节点个数的增加
	{
		score++;
		return student(id, score - 1);
	}
	student operator--(int) //头节点中存储节点个数的减少
	{
		score--;
		return student(id, score + 1);
	}
	friend ostream & operator<<(ostream & out, const student & t)
	{
		out << "id: " << t.id << ", score: " << t.score << endl;
		return out;
	} //student类型数据的插入运算符重载
	friend istream& operator>>(istream& in, student& t)
	{
		cout << "学号id与分数score:";
		in >> t.id >> t.score;
		return in;
	} //student类型数据的提取运算符重
};
#pragma once
#include"Node.h"
#include"student.h"
typedef student tt;
class List
{
private:
	Node* head;
public:
	List(tt n = 0);//构造
	void PrintList(); //遍历链表,进行打印
	Node* Find(tt data);
	Node* CreatNode(tt data); //创建一个结点(孤立结点)
	void InsertOrder(Node* p); //按升序插入生成链表
	void Insert(int n); //按位置插入生成链表(无序)
	~List(); //析构函数,删除所有结点
	void DeleteNode(Node* p); //删除指定结点
	void MakeEmpty(); //清空一个链表,只余表头结点,包含在析构函数当中
};


#include "List.h"
#include"Node.h"
#include<iostream>
using namespace std;
List::List(tt n)
{
	head = new Node(n);
}
void List::PrintList()
{
	Node* tempP = head->link;
	cout << head->info << " Nodes: ";
	while (tempP != NULL) {
		cout << tempP->info << '\t';//\t的意思:补全当前字符串长度到8位
		tempP = tempP->link;
	}
	cout << endl;
}
Node* List::Find(tt data)
{
	Node* tempP = head->link;
	while (tempP != NULL && tempP->info != data)
		tempP = tempP->link;
	return tempP;
	//搜索成功返回该结点地址,不成功返回NULL
}
Node* List::CreatNode(tt data)
{ //建立新节点
	Node* P = new Node(data);
	return P;
}
void List::InsertOrder(Node* p)
{
	Node* tempP = head->link, * tempQ = head;
	//tempQ指向tempP前面的一个节点
	while (tempP != NULL) {
		if (p->info < tempP->info) break;
		//找第一个比插入结点大的结点,由tempP指向
		tempQ = tempP;
		tempP = tempP->link;
	}
	p->link = tempP; //插入节点
	tempQ->link = p;
	head->info++; //头节点记录节点个数
}
void List::Insert(int n) //根据位置插入
{
	if (head->info < n || n < 0)
	{
		cout << "插入位置有误!" << endl;
		return;
	}
	Node* tempP = head; //从head开始数位置
	for (int i = 0; i < n; i++)
		tempP = tempP->link; //指针定位在插入节点前一个节点
	cout << "输入插入节点的数据:";
	tt value;
	cin >> value;
	Node* p = new Node(value); //新建将插入节点
	p->link = tempP->link; //插入
	tempP->link = p;
	head->info++; //头节点值域记录链表的个数
} 
void List::DeleteNode(Node* p)
{
	Node* tempP = head->link, * tempQ = head;
	while (tempP != NULL && tempP != p)
	{
		tempQ = tempP;
		tempP = tempP->link;
	}
	if (tempP) {
		tempQ->link = tempP->link;
		delete p;
		head->info--;
	}
}
void List::MakeEmpty()
{
	Node* tempP;
	while (head->link != NULL)
	{
		tempP = head->link;
		head->link = tempP->link;
		//把头结点后的第一个节点从链中脱离
		delete tempP; //删除(释放)脱离下来的结点
		head->info--; //节点个数减少
	}
}
List::~List()
{
	MakeEmpty();
	delete head;
}

#pragma once
#include<iostream>
#include"student.h"
typedef student tt;
class Node
{
	private:
		tt info;
		Node* link;
public:
	Node(tt n=0,Node*p=NULL):info(n),link(p){}
	friend class List;
};


/*system("cls");清空之前的结果*/
#include "List.h"
#include "Node.h"
#include"student.h"
#include <iostream>
typedef tt student;
using namespace std;
int main() {
	List pl;//创建空链表;
	tt num;
	int n1, n2;
	Node* p;
	char option;
	while (1)
	{
		cout << "\n链表操作练习:" << endl;
		cout << "1: 链表中插入新节点(无序)" << endl;
	    cout << "2 : 链表中插入新节点(有序)" << endl;
		cout << "3: 删除节点(值)" << endl;
		cout << "4: 查找节点" << endl;
		cout << "5: 遍历节点" << endl;
		cout << "6: 清空链表" << endl;
		cout << "0: 退出" << endl;
		cout << "\n请输入你的选择:";
		cin >> option	;
		switch (option) {
		case '0':
			break;
		case '1':
			system("cls");//清空之前的结果
			cout << "请输入插入节点的个数:";
			cin >> n1;
			while (n1) {
				cout << "请输入插入节点的位置:";
				cin >> n2;
				pl.Insert(n2);
				n1--;
			}
			pl.PrintList();
			break;
		case '2':
			system("cls");
			cout << "请输入插入的值:"; cin >> num;
			p = pl.CreatNode(num);
			pl.InsertOrder(p);
			pl.PrintList();
			break;
		case '3':
			system("cls");
			cout << "请输入被删除节点值:"; cin >> num;
			p = pl.Find(num);
			pl.DeleteNode(p);
			pl.PrintList();
			break;
		case '4':
			system("cls");
			cout << "请输入要查找的节点的值:"; cin >> num;
			p = pl.Find(num);
			if (p == NULL) cout << "查找失败!" << endl;
			else cout << "查找成功!" << endl;
			break; 
		case '5':
			system("cls");
			cout << "遍历链表所有数据:" << endl
				;
			pl.PrintList();
			break;
		case '6':
			system("cls");
			cout << "清空链表,只留下头节点!" << endl
				;
			pl.MakeEmpty();
			pl.PrintList();
			break;
		default:
			system("cls");
			cout << "你输入错误,请重新输入!" << endl
				;
		}
		if (option == '0')
			break;
	}
}

拷贝构造函数

List::List(const List& tl)

{

	head = new Node(0);

	Node* tempP1 = tl.head->link;

	Node* tempP2 = head;

	while (tempP1 != NULL) {
		tempP2->link = new Node(tempP1->info);
		tempP1 = tempP1->link;
		tempP2 = tempP2->link;
		head->info++;
	}
}

注意:使用时可能的报错情况
在这里插入图片描述
重点:在switch语句中每一个case中声明变量都是局部变量,都需要用括号括起来
解决办法:在构造时添加括号

switch (option) {
		case '0':
			break;
		case '1':
			system("cls");//清空之前的结果
			cout << "请输入插入节点的个数:";
			cin >> n1;
			while (n1) {
				cout << "请输入插入节点的位置:";
				cin >> n2;
				pl.Insert(n2);
				n1--;
			}
			pl.PrintList();
			{
				List p2(pl);
				p2.PrintList();
			}//添加括号限p2的作用域只在case1当中,避免作用域在其他case中不确定而报错的情况
			break;
		case '2':
void pop_back();      //删除链表尾部节点
void List::pop_back()
{
	head->info--;
	Node* temp1=head->link;
	Node* temp2 = head;
	while (temp1->link!= NULL)
	{
		temp1 = temp1->link;
		temp2 = temp2->link;
	}
	delete temp1;
	temp2->link= NULL;//必须要两个指针,在删除之后更改倒数第二个link
}

list.cpp

#include "List.h"
#include"Node.h"
#include<iostream>
using namespace std;
List::List(int n)
{
	head = new Node(n);
}
void List::PrintList()
{
	Node* tempP = head->link;
	cout << head->info << " Nodes: ";
	while (tempP != NULL) {
		cout << tempP->info << '\t';//\t的意思:补全当前字符串长度到8位
		tempP = tempP->link;
	}
	cout << endl;
}
Node* List::Find(int data)
{
	Node* tempP = head->link;
	while (tempP != NULL && tempP->info != data)
		tempP = tempP->link;
	return tempP;
	//搜索成功返回该结点地址,不成功返回NULL
}
Node* List::CreatNode(int data)
{ //建立新节点
	Node* P = new Node(data);
	return P;
}
void List::InsertOrder(Node* p)
{
	Node* tempP = head->link, * tempQ = head;
	//tempQ指向tempP前面的一个节点
	while (tempP != NULL) {
		if (p->info < tempP->info) break;
		//找第一个比插入结点大的结点,由tempP指向
		tempQ = tempP;
		tempP = tempP->link;
	}
	p->link = tempP; //插入节点
	tempQ->link = p;
	head->info++; //头节点记录节点个数
}
void List::Insert(int n) //根据位置插入
{
	if (head->info < n || n < 0)
	{
		cout << "插入位置有误!" << endl;
		return;
	}
	Node* tempP = head; //从head开始数位置
	for (int i = 0; i < n; i++)
		tempP = tempP->link; //指针定位在插入节点前一个节点
	cout << "输入插入节点的数据:";
	int value;
	cin >> value;
	Node* p = new Node(value); //新建将插入节点
	p->link = tempP->link; //插入
	tempP->link = p;
	head->info++; //头节点值域记录链表的个数
} 
void List::DeleteNode(Node* p)
{
	Node* tempP = head->link, * tempQ = head;
	while (tempP != NULL && tempP != p)
	{
		tempQ = tempP;
		tempP = tempP->link;
	}
	if (tempP) {
		tempQ->link = tempP->link;
		delete p;
		head->info--;
	}
}
void List::MakeEmpty()
{
	Node* tempP;
	while (head->link != NULL)
	{
		tempP = head->link;
		head->link = tempP->link;
		//把头结点后的第一个节点从链中脱离
		delete tempP; //删除(释放)脱离下来的结点
		head->info--; //节点个数减少
	}
}
List::~List()
{
	MakeEmpty();
	delete head;
}
List::List(const List& tl)

{

	head = new Node(0);

	Node* tempP1 = tl.head->link;

	Node* tempP2 = head;

	while (tempP1 != NULL) {
		tempP2->link = new Node(tempP1->info);
		tempP1 = tempP1->link;
		tempP2 = tempP2->link;
		head->info++;
	}
}
List& List::operator = (const List& tl)
{
	if (head->info == tl.head->info)//个数相同
	{
		Node* temp1 = tl.head->link;
	    Node* temp2 = head->link;
		while (temp1 != NULL)
		{
			temp2->info = temp1->info;
			temp1 = temp1->link;
			temp2 = temp2->link;
		}
	}
	else if (head->info < tl.head->info)//个数小
	{
		Node* temp1 = tl.head->link;
		Node* temp2 = head;
		while (temp1 != NULL) 
		{
			if (temp2->link== NULL)
			{
				temp2->link = new Node;
				temp2 = temp2->link;
				temp2->info = temp1->info;
				temp1 = temp1->link;
			}
			else
			{
				temp2->info = temp1->info;
				temp1 = temp1->link;
				temp2 = temp2->link;
			}
		}
		head->info = tl.head->info;
	}
	else if (head->info > tl.head->info)
	{
		Node* temp1 = tl.head->link;
		Node* temp2 = head->link;
		while (temp1 != NULL)
		{
			temp2->info = temp1->info;
			temp1 = temp1->link;
			temp2 = temp2->link;
		}
		while (temp2 != NULL)
		{
			Node* p = temp2;
			temp2 = temp2->link;
			delete p;
		}
		head->info = tl.head->info;
	}
	return (*this);
}
void List::push_back(int data)
{
	Node* temp1 = head->link;
	while (temp1->link != NULL)
		temp1 = temp1->link;
	Node* p = new Node(data);
	temp1->link = p;
	head->info++;
}
void List::pop_back()
{
	head->info--;
	Node* temp1=head->link;
	Node* temp2 = head;
	while (temp1->link!= NULL)
	{
		temp1 = temp1->link;
		temp2 = temp2->link;
	}
	delete temp1;
	temp2->link= NULL;//必须要两个指针,在删除之后更改倒数第二个link
}
Node* List::back()
{
	Node* temp1=head->link;
	while (temp1->link != NULL)
	{
		temp1 = temp1->link;
	}
	return temp1;
}
void List::keep(int a)
{
	Node* p1 = head->link;
	Node* p2 = head;
	Node* m;
	while (p1 != NULL)
	{
		if (p1->info != a)
		{
			p2->link = p1->link;
			Node* t = p1;
			p1 = p1->link;
			p2 = p2->link;
			delete t;
			head->info--;
		}
		else
		{
			m = p1;
			p1 = p1->link;
			p2 = p2->link;
			m->link = NULL;
		}
	}
	
}
void List::operator+=(const List& tl)
{
	head->info += tl.head->info;
	Node* p1 = head->link;
	while (p1->link != NULL)
	{
		p1 = p1->link;
	}
	Node*q1 = (tl.head)->link;
	while (q1 != NULL)
	{
		//Node*tt = new Node(q1->info);
		p1->link = new Node(q1->info);
		p1 = p1->link;
		q1 = q1->link;
	}
}
void List::combine(const List& tl)
{
	Node*q1 = tl.head->link;
	while (q1!=NULL)
	{
		Node* p = new Node(q1->info);
		InsertOrder(p);
		q1 = q1->link;
	}
}
void List::reverse()
{
	int all = head->info;
	Node*midz;
	int midi;
	if (all % 2 == 0)
	{
		int mid=all/2;
		midi = all / 2 + 1;
		midz = head->link;
		for(int i=1;i<midi;i++)
		{
			midz = midz->link;
		}//找midz
		//cout << midz->info << endl;
		for (int i = 1; i <= midi - 1; i++)//第几次交换
		{
			Node* l = head->link; Node* r = midz;
			for (int j = 1; j < i; j++)
			{
				l = l->link;
			}
			for (int j = 1; j <= mid - i; j++)
				r = r->link;
			int t = r->info;
			r->info = l->info;
			l->info = t;
		}
	}
	else
	{
		midi = (all + 1) / 2;
		midz = head->link;
		for (int i = 1; i < midi; i++)
			midz = midz->link;
		//cout << midz->info << endl;
		int ci = midi - 1;
		for (int i = 1; i <= ci; i++)
		{
			Node*l = head->link;
			Node* r = midz;
			for (int j = 1; j < i; j++)
				l = l->link;
			for (int j = 0; j <= ci - i; j++)
				r = r->link;
			int t = r->info;
			r->info = l->info;
			l->info = t;
		}
	}

}

list.h

#pragma once
#include"Node.h"
#include"student.h"
//typedef student tt;
class List
{
private:
	Node* head;
public:
	List(int n = 0);//构造
	void PrintList(); //遍历链表,进行打印
	Node* Find(int data);
	Node* CreatNode(int data); //创建一个结点(孤立结点)
	void InsertOrder(Node* p); //按升序插入生成链表
	void Insert(int n); //按位置插入生成链表(无序)
	~List(); //析构函数,删除所有结点
	void DeleteNode(Node* p); //删除指定结点
	void MakeEmpty(); //清空一个链表,只余表头结点,包含在析构函数当中
	List(const List& tl);//拷贝构造
	List& operator = (const List& tl);
	void push_back(int data);
	void pop_back();      //删除链表尾部节点
	Node* back();          //获取链表尾部指针(末节点),不删除
	void keep(int a);      //只保留值等于a值(要是用学生的话,a值是学生的score值)的节点 
	void operator+=(const List& tl); //把一个链表简单合并在链表尾部,注意tl依然是一个独立的链表
	void combine(const List& tl); //两个都是有序链表, 合并后依然有序
	void reverse();  //对链表进行头尾逆置
};
/*void pop_back();      //删除链表尾部节点

2) Node * back();          //获取链表尾部指针(末节点),不删除

3) void keep(int a);      //只保留值等于a值(要是用学生的话,a值是学生的score值)的节点 

4) void operator+=(const List & tl); //把一个链表简单合并在链表尾部,注意tl依然是一个独立的链表

5) void combine(const List & tl); //两个都是有序链表, 合并后依然有序

6)   void reverse();  //对链表进行头尾逆置*/

分文件撰写注意

1)不要乱include
2)在类外定义函数最好在.cpp
文件中撰写

链表排序与交换

注意相邻情况

void List::swap(Node* l, Node* r)
{
	Node* a = head;
	Node* b = head;
	for (; a->link != l; a = a->link);
	for (; b->link != r; b = b->link);
	Node* a1 = l->link;
	Node* b1 = r->link;
	if (b->link == a1)//相邻
	{
		a->link = r;
		r->link = l;
		l->link = b1;
		return;
	}
	a->link = r;
	r->link = a1;
	b->link = l;
	l->link = b1;
}
void List::mysort(int n)//升序
{
	//排序:学号1 总2 平均3
	switch (n)
	{
	case 1:
	{
		Node* p = head->link;
		Node* p1 = head;
		for (; p != NULL; p = p->link,p1=p1->link)
		{
			Node* min = p;
			Node* q = p->link;
			for (; q != NULL; q = q->link)
			{
				if (min->info.no > q->info.no)min = q;
			}
			if (min != p)
			{
				swap(p, min);//先后
				p = p1->link;
			}
		}
		break;
	}
	case 2:
	{
		Node* p = head->link;
		Node* p1 = head;
		for (; p != NULL; p = p->link,p1=p1->link)
		{
			Node* min = p;
			Node* q = p->link;
			for (; q != NULL; q = q->link)
			{
				if (min->info.sum > q->info.sum)min = q;
			}
			if (min != p)
			{
				swap(p, min);
				p = p1->link;
			}
		}
		break;
	}
	case 3:
	{
		Node* p = head->link;
		Node* p1 = head;
		for (; p != NULL; p = p->link,p1=p1->link)
		{
			Node* min = p;
			Node* q = p->link;
			for (; q != NULL; q = q->link)
			{
				if (min->info.average > q->info.average)min = q;
			}
			if (min != p)
			{
				swap(p, min);
				p = p1->link;
			}
		}
		break;
	}
	}
}
  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值