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

本文展示了三个实验,涉及单链表的初始化、插入、删除、查找、排序等基本操作。第一题中,实现了链表的初始化、插入元素、输出元素、查找元素位置等功能。第二题涉及职工信息管理,包括输入、显示、排序和删除职工记录。第三题给出了删除链表中最小元素的算法。所有操作的时间复杂度分析也在其中给出。
摘要由CSDN通过智能技术生成

实验三链表

一、实验目的与要求

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;
		*/

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

MorleyOlsen

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值