【数据结构】实验三:链表

news2024/12/22 18:10:23

实验三链表

一、实验目的与要求

1)熟悉链表的类型定义;

2熟悉链表的基本操作;

3灵活应用链表解决具体应用问题。

二、实验内容

1请设计一个单链表的存储结构,并实现单链表中基本运算算法。

编写程序linklist.cpp实现单链表的各种基本运算(假设单链表元素类型ElemTypechar),并在此基础上设计主程序exp.cpp完成以下功能。

§ 初始化单链表。

§ 依次插入a,b,c,d,e元素。

§ 输出单链表的元素和长度。

§ 判断单链表是否为空。

§ 输出单链表的第3个元素。

§ 输出元素a的位置。

§ 在第4个元素位置上插入f元素。

§ 查找单链表的第3个元素,如果在,则删除;如果不在,则输出找不到。

§ 释放单链表。

2请设计一个职工文件emp.dat,每个职工记录包含职工编号(no)、姓名(name)、部门号(depno)和工资数(salary)信息。设计一个单链表的存储结构,完成以下功能:

§ emp.dat文件中读取职工记录,并建立一个带头结点的单链表L

§ 输入一个职工记录。

§ 显示所有职工记录。

§ 按职工编号no对所有职工记录进行递增排序。

§ 按部门号depno对所有职工记录进行递增排序。

§ 按工资数salary,对所有职工记录进行递增排序。

§ 删除指定职工号的职工记录。

§ 删除职工文件中的全部记录。

§ 将单链表中的所有职工记录存储到职工文件emp.dat中。

3编写程序,实现在带头结点的单链表 L 中删除一个最小值结点的算法。请写出算法思想。

三、实验结果

1)请将调试通过的源代码粘贴在下面。(代码注意书写规范、主要模块要有功能注释)

第一题实验代码:

#include <iostream>
#include <cstdio>
#include <cstdlib>
#include <malloc.h>
using namespace std;
typedef char ElemType;

//定义单链表结点类型 
typedef struct LNode{
	ElemType data;
	struct LNode *next; 
}LinkList;

//初始化单链表
void InitList(LinkList *&L){
    //头节点创建 
	L=(LinkList *)malloc(sizeof(LinkList));
	L->next =NULL;
} 

//删除单链表
void DestroyList(LinkList *L){
	LinkList *p=L;
	LinkList *q=L->next ;
	while(q!=NULL){
		free(p);
		p=q;
		q=p->next ;
	}
	free(p);
} 

//判断单链表是否为空
bool ListEmpty(LinkList *L){
	if(L->next == NULL){
		return 0;//0 代表空 
	}
	else{
		return 1;//1 代表非空 
	}
}

//单链表长度计算
int ListLength(LinkList *L){
	LinkList *p=L;
	int i=0;
	while(p->next !=NULL){
		p=p->next ;
		i++;
	} 
	return i;
} 

//输出单链表
void DispList(LinkList *L){
	LinkList *p=L->next ;
	while(p->next !=NULL){
		cout<<p->data <<" ";
		p=p->next ;
	}
	cout<<p->data<<endl;
} 

//求某个元素的值 List + Location + Element 
int GetElem(LinkList *L,int i,ElemType &e){
	LinkList *p=L;
	int j=0;
	while(p!=NULL && j<i){
		j++;
		p=p->next ;
	}
	if(p==NULL){
		return 0;
	}
	else{
		e=p->data;
		return 1;
	}
} 

//查找元素位置 List + Element
int LocateElem(LinkList *L,ElemType e){
	LinkList *p=L;
	int j=0;
	while(p!=NULL && p->data ==e){
		j++;
		p=p->next ;
	}
	if(p==NULL){
		return 0;
	}
	else{
		return j+1; 
	}
} 

//插入元素 -> List + Location + Element
int ListInsert(LinkList *L,int i,ElemType e){
	LinkList *p=L;
	LinkList *s;
	int j=0;
	while(p!=NULL && j<i-1){
		j++;
		p=p->next ;
	}
	if(p==NULL){
		return 0;
	}
	else{
		s=(LinkList *)malloc(sizeof(LinkList));
		s->data =e;
		s->next =p->next ;
		p->next =s;
		return 1;
	}
}

//删除元素 -> List + Location + Element
int ListDelete(LinkList *L,int i,ElemType e){
	LinkList *p=L;
	LinkList *s;
	int j=0;
	while(p!=NULL && j<i-1){
		j++;
		p=p->next ;
	}
	if(p==NULL){
		return 0;
	}
	else{
		s=p->next ;
		if(s==NULL){
			return 0;
		}
		e=s->data ;
		p->next =s->next ;
		free(s);
		return 1;
	}
}

int main(){
	LinkList *h;
	ElemType e;
	
	cout<<endl<<"初始化单链表"<<endl;
	InitList(h);
	
	cout<<endl<<"依次插入abcde元素"<<endl;
	ListInsert(h,1,'a');
	ListInsert(h,2,'b');  
    ListInsert(h,3,'c');  
    ListInsert(h,4,'d');  
    ListInsert(h,5,'e');  
    
    cout<<endl<<"输出单链表的元素和长度"<<endl;
    DispList(h);
    cout<<"Length = "<<ListLength(h)<<endl;
    
    cout<<endl<<"判断单链表是否为空"<<endl;
    if(ListEmpty(h)==1){
    	cout<<"单链表不为空"<<endl;
	}
	else{
		cout<<"单链表为空"<<endl;
	}

	cout<<endl<<"输出单链表的第3个元素"<<endl;
	GetElem(h,3,e);
	cout<<e<<endl;

	cout<<endl<<"输出元素a的位置"<<endl;
	int location=LocateElem(h,'a');
	cout<<location<<endl;

	cout<<endl<<"在第4个元素位置上插入f元素"<<endl;
	ListInsert(h,4,'f');
	DispList(h);
    cout<<"Length = "<<ListLength(h)<<endl;

	cout<<endl<<"查找单链表的第3个元素"<<endl;
	int flag=ListDelete(h,3,e);
	if(flag==1){
		cout<<"元素存在,已经删除"<<endl;
	} 
	else{
		cout<<"元素不在,无法删除"<<endl;
	}
    DispList(h);
    cout<<"Length = "<<ListLength(h)<<endl;

	cout<<endl<<"释放单链表"<<endl;
	DestroyList(h);
	
	return 0;
}

第一题输出展示:

 第二题实验代码:

#include <cstdio>
#include <iostream>
#include <cstdlib>
#include <iomanip> 
using namespace std;

//每个职工记录的基本信息建立 
typedef struct w{
	int no;//职工编号(no)
	char name[10];//姓名(name)
	int depno;//部门号(depno)
	int salary;//工资数(salary)
	struct w* next;
}worker;

//输入一个职工记录 
void input(worker *&L){
	worker *p=(worker*)malloc(sizeof(worker));
	cout<<"请输入该职工的基本信息"<<endl; 
	cin>> p->no >> p->name >> p->depno >> p->salary ;
	//头插法 
	p->next=L->next ;
	L->next =p;
	cout<<"已完成,可输入2进行查询"<<endl;
}

//显示所有职工记录
void show(worker *L){
	worker *p=L->next ;
	for(p=L->next;p!=NULL;p=p->next ){
		cout<<"  no:"<<setw(12)<<p->no
		<<"  name:"<<setw(12)<<p->name
		<<"  depno:"<<setw(12)<<p->depno
		<<"  salary:"<<setw(12)<<p->salary<<endl;
	}
	cout<<endl; 
}

//按照no排序
void no_sort(worker *&L){
	worker *p,*q,*s;
	if(L->next ==NULL){
		cout<<"当前链表为空"<<endl;
		return;
	}
	q=L->next->next;
	L->next->next=NULL;
	while(q!=NULL){
		p=L;
		while(p->next !=NULL && q->no >= p->next ->no){
			p=p->next ;
		}
		s=q->next ;
		q->next =p->next ;
		p->next =q;
		q=s;
	}
	cout<<"已完成,可输入2进行查询"<<endl;
} 

//按照depno排序 
void depno_sort(worker *&L){
	worker *p,*q,*s;
	if(L->next==NULL){
		cout<<"当前链表为空"<<endl;
		return ;
	}
	q=L->next ->next;
	L->next ->next=NULL;
	while(q!=NULL){
		p=L;
		while(p->next !=NULL && q->depno >=p->next ->depno){
			p=p->next ;
		}
		s=q->next ;
		q->next =p->next ;
		p->next =q;
		q=s;
	}
	cout<<"已完成,可输入2进行查询"<<endl;
}

//按照salary排序 
void salary_sort(worker *&L){
	worker*p,*q,*s;       
	if(L->next==NULL){
		printf("链表为空\n");
		return;
	}
	q=L->next->next;
	L->next->next=NULL;
	while(q!=NULL){
		p=L;
		while(p->next!=NULL && q->salary >= p->next->salary){
			p=p->next;
		}
		s=q->next;
		q->next=p->next;
		p->next=q;
		q=s;
	}
	cout<<"已完成,可输入2进行查询"<<endl;
}

//删除指定职工号的职工记录
void listdelete(worker *&L){
	worker *p,*temp;
	int num;
	cout<<"请输入要删除职工的工号:"<<endl;
	cin>>num;
	for(p=L;p->next !=NULL;p=p->next ){
		if(p->next ->no==num){
			temp=p->next ;
			p->next =temp->next;
			free(temp);
			break;
		}
	}
	cout<<"已完成,可输入2进行查询"<<endl;
}

//删除职工文件中的全部记录
void destroy(worker *&L){
	worker *p=L->next;
	worker *q;
	while(p!=NULL){
		q=p;
		p=p->next;
		free(q);
	}
	L->next=NULL;
	cout<<"已完成,可输入2进行查询"<<endl;
} 

//生成用户界面
void book(){
	cout<<endl;
    cout<<"本链表可以进行以下操作"<<endl; 
	cout<<"1:输入一个职工记录"<<endl; 
	cout<<"2:显示所有职工记录"<<endl;
	cout<<"3:按职工编号no对所有职工记录进行递增排序"<<endl;
	cout<<"4:按部门号depno对所有职工记录进行递增排序"<<endl;
	cout<<"5:按照工资数salary对所有职工记录进行递增排序"<<endl;
	cout<<"6:删除制定职工号的职工记录"<<endl;
	cout<<"7:删除职工文件中的全部记录"<<endl;
	cout<<"8:结束本次操作"<<endl;
}

int main(){
    //初始化链表 
	worker*L=(worker*)malloc(sizeof(worker));
	L->next=NULL;
	
	while(1){
		int opt;
		book();
		cout<<"请输入以上数字进行职工信息操作:"; 
		cin>>opt;
		switch(opt){
			case 1://输入一个职工记录 
				input(L);
				break;
			case 2:
				show(L);
				break;
			case 3:
				no_sort(L);
				break;
			case 4:
				depno_sort(L);
				break;
			case 5:
				salary_sort(L);
				break;
			case 6:
				listdelete(L);
				break;
		    case 7:
		    	destroy(L);
		    	break;
		    case 8:
		    	return 0;
		    default:
		    	cout<<"输入数字有误,请重新输入"<<endl; 
		}
	}
}

第二题输出展示:

操作1:

 

 操作2:

 操作3:

 操作4:

 操作5:

 操作6:

 操作7:

 操作8:

 第三题实验代码:

void delminnode(LinkNode *L){
	LinkNode *r=L,*p=L->next,*q=p->next,*s=p;//p总是指向最小结点,r总是指向p的前驱结点,q遍历,s指向q的前驱结点
	while(q!=NULL){
		if(p->data > q->data){
			r=s;         //p>q时,r指向p 
			p=q;         //p总是指向最小结点 
			q=q->next;   //q向后遍历 
			s=s->next;
		}
		else{
		    q=q->next; 
		    s=s->next;
		}
	} 
	r->next = p->next;
	free(p); //删除p结点
}

2)请分析你程序中每个功能模块的算法时间复杂度。

第一题:

p从头结点开始遍历,每经过一个非空元素就通过free(p)进行删除,同时重置p为其后继结点q,重置q为q的后继结点。由此可见,时间复杂度为O(n)。

 

只需要对头结点的后继结点进行判断,因为头结点不存放数据,所以若后继结点非空则链表非空,若后继结点为空则链表为空。由此可见,时间复杂度为O(1)。

 

通过p遍历链表,计算链表所存储的元素个数,遇到空指针便结束计算。由此可见,时间复杂度为O(n)。

 

通过p遍历链表,输出链表所存储的每一个元素,遇到空指针便结束输出。由此可见,时间复杂度为O(n)。

 

本段代码是求指定位置的元素,通过遍历单链表从头结点摸索到指定位置的结点并输出其对应的元素。由此可见,时间复杂度为O(n)。

 

本段代码是求指定元素的位置,通过遍历单链表从头结点摸索每一个位置的元素是否与已知元素等同,若等同则输出相应的位置。由于初始化计数变量j是从0开始计数的,因此在最后需要进行+1操作。由此可见,时间复杂度为O(n)。

 

本段代码是在指定位置插入指定元素,通过while循环确定所需要插入的元素的前驱结点,再插入指定元素。由此可见,时间复杂度为O(n)。

 

本段代码是在指定位置删除元素,思路与在指定位置插入指定元素类似,主要是通过while循环确定所需要删除的元素的。由此可见,时间复杂度为O(n)。

 

第二题:

本段代码是直接插入一打数据,不需要遍历单链表。由此可见,时间复杂度为O(1)。

 

本段代码是通过从头结点遍历单链表,找到每一个结点所存储的数据并输出。由此可见,时间复杂度为O(n)。

 

本段代码是按照工号对职工信息进行排序,实现过程主要是通过两个while循环。外层循环是从头结点遍历到最后一个结点,并假设头结点所存的工号元素为最小值,内层循环是比较下一个结点与当前结点所存工号元素的大小,若不存在大小突变,则继续通过p遍历单链表。由此可见,时间复杂度为O(n²)。

 

本段代码是按照部门号对职工信息进行排序,实现过程主要是通过两个while循环。外层循环是从头结点遍历到最后一个结点,并假设头结点所存的部门号元素为最小值,内层循环是比较下一个结点与当前结点所存部门号元素的大小,若不存在大小突变,则继续通过p遍历单链表。由此可见,时间复杂度为O(n²)。

 

本段代码是按照工资对职工信息进行排序,实现过程主要是通过两个while循环。外层循环是从头结点遍历到最后一个结点,并假设头结点所存的工资元素为最小值,内层循环是比较下一个结点与当前结点所存工资元素的大小,若不存在大小突变,则继续通过p遍历单链表。由此可见,时间复杂度为O(n²)。

 

本段代码是删除指定的职工信息,主要通过从头结点遍历单链表实现。当for循环中遇到与指定工号相同的工号元素时,通过free()进行删除该元素组。由此可见,时间复杂度为O(n)。

 

本段代码是删除指定的职工信息,主要通过从头结点遍历单链表实现。通过while循环摸到该单链表的尾部,在遇到每一个元素组的时候,通过free()进行删除该元素组,最后将头指针的后继结点重置为NULL。由此可见,时间复杂度为O(n)。

 

第三题:

算法思想:q从头结点指向的下一个结点开始遍历直到链表结束,每一次寻找到最小值就存入p中,遇到更小的值就进行替换。遍历完成后,最小值p且r为p的前驱结点,然后删除p即可获得最终效果。由此可见,时间复杂度为O(n)。

 


其他参考代码:

#include<iostream>
#include<stdio.h>
using namespace std;
#define Elemtype char               //最后没有分号 
//typedef LNode *LinkList;         //LinkList和LNode*   是不同的名字,但是他们是同一个指针类型,命名的不同是为了概念上更加明确。
//这里的LinkList类型的指针变量L表示它是单链表的头指针,LNode* 类型的指针变量表示它是指向某一结点的指针 
class LNode{
	private:
	Elemtype data;
	LNode *next;
	public:
	LNode()
	{
		this->next=NULL;
	}
	/*
	void InitList_L(LNode* &L)    //链表初始化函数 
	{
		L=new LNode;
		L->next=NULL; 
	}
	void DestroyList_L(LNode* &L)  //对于结构体:销毁函数  从 头结点 开始,依次释放表中每一个节点所占用的存储空间 
	{
		LNode *p;
		p=new LNode;      
		p->next=NULL;                
		while(L)                    //如果L存放的东西不为空,也即L指向的地方不为空,那就接着循环。 这样可以找到最后一个结点 
		{
			p=L;                   //p指向的地方和L指向的地方一样             
//p仅仅指向现在的L指向的这一个地方,即头结点,每一次删头结点,之前的第一个成为了头结点,那就接着删 
//确实是可以通过p把L里面的一个一个删除,只删p的话就是只删了这一个结点 
			L=L->next;            //L是一个指针,指向L这个结点,也就是头结点。 L->next指的是第L+1个结点,也就是第一个结点 
			delete p;           
			p->next=NULL;       
		}
	}
	void ClearList_L(LNode* &L)   //对于结构体:清空函数  从单链表  第一个  节点开始,依次释放表中每一个节点所占用的存储空间 
	{
		LNode *p;
		LNode *q;
		p=L->next;                 //L是头结点,L存着的就是头结点的物理地址。所以L->next就是第一个节点的物理地址   
		q=new LNode;        //所以用这样的方法new出来的就是这个地址的头结点 
		while(p)
		{
			q=p;
			p=p->next;
			delete q;
			q->next=NULL;
		} 
		L->next=NULL;             
	} 
	*/
	void pushback(Elemtype t)       //在链表最后面添加元素 
	{
		LNode *p;
		p=new LNode;               //存放数据的LNode* 指针要new,不new会出大问题。只用作遍历可以不new 
		p->next=NULL;
		p->data=t;
		LNode *pp;                
		pp=this;                   
		while(pp->next!=NULL)
		{
			pp=pp->next;
		}
		pp->next=p;
	}
	void show()                  //按顺序输出链表元素 
	{
		LNode *p;
		p=this;
		while(p->next!=NULL)
		{
			cout<<p->next->data<<" ";
			p=p->next;
			
			//cout<<"!"<<endl;
		}
	}
	int getLength()                                //输出链表长度 
	{
		LNode* p;
		p=this;
		int i=0;
		while(p->next!=NULL)
		{
			i++;
			p=p->next;
		}
		return i;
	}
	bool isEmpty()                       //判断链表是否为空表 
	{
		LNode *p;
		p=this;
		if(p->next==NULL)
		{
			return 1;
		}
		else
		{
			return 0;
		}
	}
	Elemtype threeShow()               //输出第三元素所在的位置 
	{
		LNode *p;
		p=this;
		int i=0;
		for(i=0;i<3;i++)
		{
			p=p->next;
		}
		return p->data;
	}
	int concernA()    //判断字母a是否在链表里面,如果在,就输出位置 
	{
		LNode *p;
		p=this->next;
		int i=0;
		while(1)
		{
			if(p->data=='a')
			{
				break;
			}
			else
			{
				i++;
			}
			p=p->next;
			if(i==5)
			{
				break;
			}
		}
		if(i==5)
		{
			return 0;
		}
		else
		{
			return i+1;
		}
	}
	void insert(Elemtype m,int n)         //在指定地方插入元素 
	{
		int i=0;
		LNode* p;
		p=new LNode;
		p->data=m;
		p->next=NULL;
		LNode *q;
		q=this;
		for(i=0;i<n-1;i++)
		{
			q=q->next;
		}
		p->next=q->next;
		q->next=p;
		cout<<"已经按需插入"<<endl; 
	}
	void Mydelete(int n)                  //删除指定位置的元素 
	{
		LNode *p;
		p=this;
		int i=0;
		if((*this).getLength()>=n+1)
		{
			for(i=0;i<n-1;i++)
			{
				p=p->next;
			}
			LNode* q;
			q=p->next;
			p->next=p->next->next;
			delete q;
			q->next=NULL;
			cout<<"删除了第"<<n<<"个元素"<<endl;
		}
		else if((*this).getLength()==n)
		{
			for(i=0;i<n-1;i++)
			{
				p=p->next;
			}
			LNode* q;
			q=p->next;
			p->next=NULL;
			delete q;
			q->next=NULL;
			cout<<"删除了第"<<n<<"个元素"<<endl;
		}
		else
		{
			cout<<"长度不足三,没有第三个元素"<<endl;
		}
	}
	~LNode()                            //析构函数 
	{
		cout<<endl<<"析构函数调用!"<<endl;
	}
	/*
	~LNode()                          //析构函数:  注意!!!想删除头结点,得用头删法,从头开始删 
	{
		LNode *L;
		L=this;
		LNode *p;
		p=new LNode;
		p->next==NULL;
		int i=0;
		while(L)
		{
			p=L;
			L=L->next;
			delete p;
			p->next=NULL;
			cout<<i;
			i++;
		} 
		cout<<"析构函数调用!"<<endl;
	}
	*/
};
int main()
{
	Elemtype t;
	LNode a;
	int i=0;
	while(i<5)
	{
		cin>>t;
		a.pushback(t); 
		i++;
	}
	cout<<"链表长度为:"<<a.getLength()<<endl;
	if(a.isEmpty()==1)
	{
		cout<<"链表为空"<<endl;
	}
	else
	{
		cout<<"链表不为空"<<endl;
	}
	cout<<"链表中第三个元素为:"<<a.threeShow()<<endl;
	if(a.concernA()==0)
	{
		cout<<"没有字母a"<<endl;
	} 
	else
	{
		cout<<"字母a的位置为:"<<a.concernA()<<endl;
	} 
	Elemtype f='f';
	a.insert(f,4);
	int pos=3;
	a.show();
	cout<<endl;
	a.Mydelete(pos);
	a.show();
} 
#include<iostream>
#include<cmath>
#include<algorithm>
#include<cstdio>
#include<cstring>
#include<cstdlib>
#include<fstream>
#include<vector>
using namespace std;
typedef long long ll;
struct emp{
	int salary;                        //薪水
	string name,depno,id;             //姓名、部门编号、职工号
};

ostream& operator << (ostream& out,const emp p)          //输出流
{
	out<<p.id<<" "<<p.name<<" "<<p.depno<<" "<<p.salary;
	return out;
}
bool cmp1(emp a,emp b){
	return a.salary<b.salary;
}
template<typename T>
class List{
	private:
		T data;
		List *link;
	public:
		List();
		~List();
		void append(const T& val);	           // 链尾增加一个元素
        void insertElement(int pos,const T& val);	 // 在指定位置pos后添加一个元素val
        void deleteElement(const string& val);	               // 删除所有值为val的元素 ,有析构函数时,这个delete也可能引起析构函数的调用。 
        void travalList()const;             // 从头节点遍历输出链表并输出长度
        bool isEmpty() const;               //判断是否为空
		void elementPos(const int& pos);   //输出第pos+1位置 因为从0开始计算
		void findElement(const T& val);    //输出b元素为val的位置
		void findDelete(const int& pos);  //查找并删除


		void deletetxt();                   //删除文本内容
		void nwlist();                      //读取职工记录
		void gtin();                        //读入一个记录

		void sortSalary();//以下为排序
		void sortId();
		void sortDepno();
		void writeTxt();//写入文件
};

template<typename T>
List<T>::List(){
	link=NULL;
}

template<typename T>
void List<T>::append(const T& val){
	List* head=this;
	while((head->link)!=NULL){
		head=head->link;
	}
	List<T> *a = new List();
	a->data=val;
	head->link=a;
}


template<typename T>
void List<T>::deleteElement(const string& val)
{
	int flag=0;
	List* head=this;
	while((head->link)!=NULL)
	{
		if(head->link->data.id==val)
		{
			flag=1;
			List* tmp=head->link;
			head->link=tmp->link;
			tmp->link=NULL;
			delete tmp;
			continue;
		}
		if(head->link==NULL) break;
		head=head->link;
	}
	if(flag==0)
	{
		cout<<"\nElement "<<val<<" not Found.";
	}
}


template<typename T>
void List<T>::travalList()const
{
	int l=0;
	List* head=this->link;
	while(head!=NULL)
	{
		l++;
		cout<<head->data<<endl;
		head=head->link;
	}
	cout<<"\nlength: "<<l<<endl;
}


template<typename T>
List<T>::~List()
{
  if(this->link!=NULL)
  {
  	delete this->link;
  	this->link=NULL;
  }
}




template<typename T>
void List<T>::deletetxt()
{

	ofstream f("emp.dat",ios::trunc);
	f.close();
}

template<typename T>
void List<T>::nwlist()
{
	FILE* fp;
	fp=freopen("emp.dat","r",stdin);
	int l;
	cin>>l;
	for(int i=1;i<=l;i++)
	{
	  	emp tmp;
	 		cin>>tmp.id>>tmp.name>>tmp.depno>>tmp.salary;
		 	this->append(tmp);
	 }
	 fclose(fp);
}


template<typename T>
void List<T>::gtin()
{
	emp tmp;
	cin>>tmp.id>>tmp.name>>tmp.depno>>tmp.salary;
	this->append(tmp);
}

template<typename T>
void List<T>::sortSalary()
{
	vector<emp> q;
	List* head=this->link;
	while(head!=NULL)
	{
		q.push_back(head->data);
		head=head->link;
	}
	for(int i=0;i<q.size()-1;i++)
	{
		for(int j=0;j<q.size()-1-i;j++)
		{
			if(q[j].salary>q[j+1].salary)
			{
				emp tmp=q[j];
				q[j]=q[j+1];
				q[j+1]=tmp;
			}
		}
	}
	head=this->link;
	int l=0;
	while(head!=NULL)
	{
		head->data=q[l];
		l++;
		head=head->link;
	}
}

template<typename T>
void List<T>::sortId()
{
	vector<emp> q;
	List* head=this->link;
	while(head!=NULL)
	{
		q.push_back(head->data);
		head=head->link;
	}
	for(int i=0;i<q.size()-1;i++)
	{
		for(int j=0;j<q.size()-1-i;j++)
		{
			if(q[j].id>q[j+1].id)
			{
				emp tmp=q[j];
				q[j]=q[j+1];
				q[j+1]=tmp;
			}
		}
	}
	head=this->link;
	int l=0;
	while(head!=NULL) 
	{
		head->data=q[l];
		l++;
		head=head->link;
	}
}

template<typename T>
void List<T>::sortDepno()
{
	vector<emp> q;
	List* head=this->link;
	while(head!=NULL)
	{
		q.push_back(head->data);
		head=head->link;
	} 
	for(int i=0;i<q.size()-1;i++){
		for(int j=0;j<q.size()-1-i;j++)
		{
			if(q[j].depno>q[j+1].depno)
			{
				emp tmp=q[j];
				q[j]=q[j+1];
				q[j+1]=tmp;
			}
		}
	}
	head=this->link;
	int l=0;
	while(head!=NULL)
	{
		head->data=q[l];
		l++;
		head=head->link;
	}
}


template<typename T>
void List<T>::writeTxt()                      
{
	FILE* fp;
	fp=freopen("emp.dat","w",stdout);
	vector<emp> q;
	List* head=this->link;
	while(head!=NULL)
	{
		q.push_back(head->data);
		head=head->link;
	}
	cout<<q.size()<<endl;
	for(int i=0;i<q.size();i++)
	{
		cout<<q[i].id<<" "<<q[i].name<<" "<<q[i].depno<<" "<<q[i].salary<<endl;
	}
	fclose(fp);
}

int main() 
{
	List<emp> list;
	list.nwlist();
	list.travalList();
	list.sortSalary();
	list.travalList();
	list.sortDepno();
	list.travalList();
	list.deleteElement("001");
	list.travalList();
	list.deletetxt();
	list.writeTxt();
    return 0;
}
//在单链表里面删除一个最小结点的算法
#include<iostream>
#include<stdio.h>
using namespace std;
#define Elemtype double               //最后没有分号 
//typedef LNode *LinkList;            //LinkList和LNode*   是不同的名字,但是他们是同一个指针类型,命名的不同是为了概念上更加明确。
//这里的LinkList类型的指针变量L表示它是单链表的头指针,LNode* 类型的指针变量表示它是指向某一结点的指针 
class LNode{
	private:
	Elemtype data;
	LNode *next;
	public:
	LNode()
	{
		this->next=NULL;
	}
	void pushback(Elemtype t)       //在链表最后面添加元素 
	{
		LNode *p;
		p=new LNode;               //存放数据的LNode* 指针要new,不new会出大问题。只用作遍历可以不new 
		p->next=NULL;
		p->data=t;
		LNode *pp;               
		pp=this;                 
		while(pp->next!=NULL)
		{
			pp=pp->next;
		}
		pp->next=p;
	}
	void show()                                //按顺序输出链表元素 
	{
		LNode *p;
		p=this;
		while(p->next!=NULL)
		{
			cout<<p->next->data<<" ";
			p=p->next;
		}
	}
	int getLength()                                //输出链表长度 
	{
		LNode* p;
		p=this;
		int i=0;
		while(p->next!=NULL)
		{
			i++;
			p=p->next;
		}
		return i;
	}
	void Mydelete(int n,int flag)             //删除指定位置的元素 
	{
		LNode *p;
		p=this;
		int i=0;
		if((*this).getLength()>=n+1)
		{
			for(i=0;i<n-1;i++)
			{
				p=p->next;
			}
			LNode* q;
			q=p->next;
			p->next=p->next->next;
			delete q;
			q->next=NULL;
			cout<<"删除了第"<<n<<"个元素"<<endl;
		}
		else if((*this).getLength()==n)
		{
			for(i=0;i<n-1;i++)
			{
				p=p->next;
			}
			LNode* q;
			q=p->next;
			p->next=NULL;
			delete q;
			q->next=NULL;
			cout<<"删除了第"<<n<<"个元素"<<endl;
		}
		else
		{
			cout<<"长度不足三,没有第三个元素"<<endl;
		}
		
	}
	~LNode()                            //析构函数 
	{
		cout<<endl<<"析构函数调用!"<<endl;
	}
	void min()
	{
		LNode *p;
		p=this->next;
		int len=(*p).getLength()+1;    //因为,它此时初始位置为this->next而不是this,所以求出来长度少一 
		Elemtype s[10]={0},temp=0;
		int i=0,flag[100]={0},j=0;
		for(i=0;i<len;i++)
		{
			s[i]=p->data;
			p=p->next;
		}
		temp=s[0];
		for(i=1;i<len;i++)
		{
			if(s[i]<temp)
			{
				temp=s[i];
			}
		}
		for(i=0;i<len;i++)
		{
			if(s[i]==temp)
			{
				flag[j]=i;
				j++;
			}
		}
		int k=0;
		for(k=0;k<j;k++)
		{
			(*this).Mydelete(flag[k]+1,k);
		}
		
	}
}; 
int main()
{
	Elemtype t;
	LNode a;
	int i=0;
	while(i<5)
	{
		cin>>t;
		a.pushback(t); 
		i++;
	}
	a.show();
	a.min();
	a.show();
} 





/*
		LNode *p;
		p=this;
		LNode *f;
		f=new LNode;
		int i=0;
		if(n==1)
		{
			f=p->next;
			p->next=p->next->next;
			delete f;
			f->next=NULL;
		}
		if(n==2&&flag==1)
		{
			f=p->next;
			p->next=p->next->next;
			delete f;
			f->next=NULL;
		}
		for(i=0;i<n-1-flag;i++)
		{
			p=p->next;
		}
		f=p->next;
		p->next=p->next->next;
		delete f;
		f->next=NULL;
		*/

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/801201.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

基于ssm+mysql+jsp高校疫情防控出入信息管理系统

基于ssmmysqljsp高校疫情防控出入信息管理系统 一、系统介绍二、功能展示1.登陆2.教师管理3.学生管理4.打卡记录管理5.学生申请通行证6.通行证管理7.留言信息管理8.公告类型管理9.公告管理 四、获取源码 一、系统介绍 学生 : 个人中心、打卡记录管理、学生申请通行证、通行证管…

Java 8 Stream流:代码简洁之道

文章目录 前言一、filter二、map三、mapToInt、mapToLong、mapToDouble四、flatMap五、flatMapToInt、flatMapToLong、flatMapToDouble六、distinct七、sorted八、peek九、limit十、forEach十一、forEachOrdered十二、toArray十三、reduce十四、collect十五、min、max十六、cou…

mysql(二) 索引-基础知识

继续整理复习、我以我的理解和认知来整理 "索引" 会通过 文 和 图 来展示。 文&#xff1a; 基本概念知识&#xff08;mysql 的索引分类、实现原理&#xff09; 图&#xff1a; 画B树等 MySQL官方对索引的定义是&#xff1a;索引&#xff08;Index&#xff09;是帮…

记录--虚拟 DOM 和实际 DOM 有何不同?

这里给大家分享我在网上总结出来的一些知识&#xff0c;希望对大家有所帮助 前言 本文我们会先聊聊 DOM 的一些缺陷&#xff0c;然后在此基础上介绍虚拟 DOM 是如何解决这些缺陷的&#xff0c;最后再站在双缓存和 MVC 的视角来聊聊虚拟 DOM。理解了这些会让你对目前的前端框架有…

第四章 HL7 架构和可用工具 - 查看数据结构

文章目录 第四章 HL7 架构和可用工具 - 查看数据结构查看数据结构查看代码表使用自定义架构编辑器 第四章 HL7 架构和可用工具 - 查看数据结构 查看数据结构 当单击“数据结构”列中的名称时&#xff0c;InterSystems 会显示该数据结构中的所有字段。这是 HL7 数据结构页面。…

影视行业案例 | 燕千云助力大地影院集团搭建智能一体化IT服务管理平台

影视行业过去三年受新冠肺炎疫情影响&#xff0c;经历了一定程度的冲击和调整&#xff0c;但也展现出了强大的韧性和潜力。2023年中国影视产业规模可能达到2600亿元左右&#xff0c;同比增长11%左右。影视行业的发展趋势主要表现在内容创新、模式创新和产业融合三个方面&#x…

第八章:将自下而上、自上而下和平滑性线索结合起来进行弱监督图像分割

0.摘要 本文解决了弱监督语义图像分割的问题。我们的目标是在仅给出与训练图像关联的图像级别对象标签的情况下&#xff0c;为新图像中的每个像素标记类别。我们的问题陈述与常见的语义分割有所不同&#xff0c;常规的语义分割假设在训练中可用像素级注释。我们提出了一种新颖的…

PSP - MMseqs2 编译最新版本源码 (14-7e284) 支持 MPI 功能 MSA 快速搜索

欢迎关注我的CSDN&#xff1a;https://spike.blog.csdn.net/ 本文地址&#xff1a;https://spike.blog.csdn.net/article/details/131966061 MPI (Message Passing Interface) 是用于并行计算的标准化和可移植的消息传递接口&#xff0c;可以在分布式内存的多台计算机上运行并行…

操作系统、人工智能、芯片和其它

最近出差一段时间&#xff0c;听到一些事&#xff0c;看到一些事&#xff0c;说点个人观感。有些话可能不好听&#xff0c;还希望不要被平台和谐。   从一位现在微软工作的前同事处得来的消息&#xff0c;微软下一代操作系统Windows 12将深度集成AI&#xff0c;如果再加上的它…

彻底搞懂CPU的特权等级

x86 处理器中,提供了4个特权级别:0,1,2,3。数字越小,特权级别越高! 一般来说,操作系统是的重要性、可靠性是最高的,需要运行在 0 特权级; 应用程序工作在最上层,来源广泛、可靠性最低,工作在 3 特权级别。 中间的1 和 2 两个特权级别,一般很少使用。 理论上来讲,…

redis到底几个线程?

通常我们说redis是单线程指的是从接收客户端请求->解析请求->读写->响应客户端这整个过程是由一个线程来完成的。这并不意味着redis在任何场景、任何版本下都只有一个线程 为何用单线程处理数据读写&#xff1f; 内存数据储存已经很快了 redis相比于mysql等数据库是…

集合---list接口及实现类

一、list概述 1、list接口概述 List接口继承自Collection接口&#xff0c;是单列集合的一一个重要分支&#xff0c;我们习惯性地会将实现了 List接口的对象称为List集合。在List集合中允许出现重复的元素&#xff0c;所有的元素是以一种线性方 式进行有序存储的&#xff0c;在…

在linux中怎样同时运行三个微服务保证退出时不会终止

前言 1.maven中打jar包 使用插件打包,必须在pom.xml中添加插件,否则不能在linux中编译运行 <build><plugins><plugin><groupId>org.springframework.boot</groupId><artifactId>spring-boot-maven-plugin</artifactId><version&g…

RISC-V公测平台发布 · 第一个WEB Server “Hello RISC-V world!”

RISC-V公测平台Web Server地址&#xff1a;http://175.8.161.253:8081 一、前言 Web Server是互联网应用的基础设施&#xff0c;无论是用户访问网站&#xff0c;还是后端服务提供商和开发者构建各种应用程序&#xff0c;Web Server都在其中扮演着至关重要的角色。 显而易见…

甄品焕新 | 链接上下游企业服务协同,改变服务获取方式

文/玉娇龙 本文字数&#xff1a;3500&#xff5c;预计3分钟读完 使用燕千云上下游服务管理&#xff0c;你可以统一管理IT服务供应商、业务经销商、客户等业务伙伴的服务往来&#xff0c;将企业与上下游公司之间的工单服务往来进行统一管理、共享与升级&#xff0c;实现服务共享…

jmeter接口测试、压力测试简单实现

jmeter测试的组件执行顺序&#xff1a; 测试计划—>线程组—>配置元件—>前置处理器—>定时器—>逻辑控制器—>取样器—>后置处理器—>断言—>监听器 组件的作用范围&#xff1a; 同级组件同级组件下的子组件父组件 目前市面上的三类接口 1、基…

netty 809协议

netty 809协议 目录概述需求&#xff1a; 设计思路实现思路分析1.netty 809 协议2.概念代码 参考资料和推荐阅读 Survive by day and develop by night. talk for import biz , show your perfect code,full busy&#xff0c;skip hardness,make a better result,wait for chan…

ad+硬件每日学习十个知识点(15)23.7.26 (逻辑器件、拉电流和灌电流、OC门和OD门、总线保持)

文章目录 1.逻辑器件介绍2.什么是总线缓冲器&#xff1f;3.逻辑器件按功能分类4.逻辑器件按工艺分类&#xff08;目前主要用CMOS逻辑&#xff09;5.什么是总线保持&#xff1f;6.逻辑电平7.两个逻辑器件互连&#xff0c;需要满足什么要求&#xff1f;8.什么是推挽&#xff0c;什…

关于自签名证书授权后在哪儿看

目录 firefox可以看到 chrome and edge firefox可以看到 chrome and edge 只能从打开的网站左上角进入

读《全球科技通史》总结——历史总在重演,科技永远向前

今天和大家分享一下吴军老师的《全球科技通史》。大部分人谈到历史的时候&#xff0c;关注的是国家的兴衰、王朝的更替&#xff0c;往往忽视了科技的力量。“文津图书奖”得主吴军博士&#xff0c;从科技视角串联历史&#xff0c;首次以能量和信息两条主线&#xff0c;系统阐述…