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

这篇具有很好参考价值的文章主要介绍了【数据结构】实验三:链表。希望对大家有所帮助。如果存在错误或未考虑完全的地方,请大家不吝赐教,您也可以点击"举报违法"按钮提交疑问。

实验三链表

一、实验目的与要求

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;
}

第一题输出展示:

数据结构实验3,数据结构,数据结构,链表

 第二题实验代码:

#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:

数据结构实验3,数据结构,数据结构,链表

 数据结构实验3,数据结构,数据结构,链表

 操作2:

数据结构实验3,数据结构,数据结构,链表

 操作3:

数据结构实验3,数据结构,数据结构,链表

 操作4:

数据结构实验3,数据结构,数据结构,链表

 操作5:

数据结构实验3,数据结构,数据结构,链表

 操作6:

数据结构实验3,数据结构,数据结构,链表

 操作7:

数据结构实验3,数据结构,数据结构,链表

 操作8:

数据结构实验3,数据结构,数据结构,链表

 第三题实验代码:

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)请分析你程序中每个功能模块的算法时间复杂度。

第一题:

数据结构实验3,数据结构,数据结构,链表

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

 

数据结构实验3,数据结构,数据结构,链表

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

 

数据结构实验3,数据结构,数据结构,链表

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

 

数据结构实验3,数据结构,数据结构,链表

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

 

数据结构实验3,数据结构,数据结构,链表

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

 

数据结构实验3,数据结构,数据结构,链表

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

 

数据结构实验3,数据结构,数据结构,链表

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

 

数据结构实验3,数据结构,数据结构,链表

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

 

第二题:

数据结构实验3,数据结构,数据结构,链表

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

 

数据结构实验3,数据结构,数据结构,链表

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

 

数据结构实验3,数据结构,数据结构,链表

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

 

数据结构实验3,数据结构,数据结构,链表

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

 

数据结构实验3,数据结构,数据结构,链表

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

 

数据结构实验3,数据结构,数据结构,链表

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

 

数据结构实验3,数据结构,数据结构,链表

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

 

第三题:

数据结构实验3,数据结构,数据结构,链表

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

 


其他参考代码:文章来源地址https://www.toymoban.com/news/detail-744633.html

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

到了这里,关于【数据结构】实验三:链表的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处: 如若内容造成侵权/违法违规/事实不符,请点击违法举报进行投诉反馈,一经查实,立即删除!

领支付宝红包 赞助服务器费用

相关文章

  • C语言---数据结构实验---顺序表的合并---链表的基本操作---重点解析约瑟夫问题

    实验的写法多种多样,但本文并未采用 #define 定义容量的写法,这样写已经是很老旧过时的写法。所有实验主体采用均为动态开辟,后续如果利用 C++ 来写或许会应用更多语法… 本篇展示数据结构的两个实验 其中,重点分析约瑟夫问题 实验中代码的命名风格等均与下方博客

    2024年02月16日
    浏览(70)
  • 数据结构-链表结构-双向链表

    双向链表也叫双链表,与单向链表不同的是,每一个节点有三个区域组成:两个指针域,一个数据域 前一个指针域:存储前驱节点的内存地址 后一个指针域:存储后继节点的内存地址 数据域:存储节点数据 以下就是双向链表的最基本单位 节点的前指针域指向前驱,后指针

    2024年02月04日
    浏览(47)
  • <数据结构> 链表 - 链表的概念及结构

    概念: 链表是一种物理存储结构上非连续、非顺序的存储结构,数据元素的 逻辑顺序 是通过链表中的 指针链接 次序实现的 1、链表由一系列结点(链表中每一个元素称为结点)组成。 2、结点可以在运行时动态(malloc)生成。 3、每个结点包括两个部分:一个是存储数据元素的

    2023年04月09日
    浏览(46)
  • 【数据结构-链表-01】反转链表

    💝💝💝欢迎来到我的博客,很高兴能够在这里和您见面!希望您在这里可以感受到一份轻松愉快的氛围,不仅可以获得有趣的内容和知识,也可以畅所欲言、分享您的想法和见解。 推荐:kuan 的首页,持续学习,不断总结,共同进步,活到老学到老 导航 檀越剑指大厂系列:全面总

    2024年02月10日
    浏览(44)
  • 数据结构——线性数据结构(数组,链表,栈,队列)

    数组(Array) 是一种很常见的数据结构。它由相同类型的元素(element)组成,并且是使用一块连续的内存来存储。 我们直接可以利用元素的索引(index)可以计算出该元素对应的存储地址。 数组的特点是: 提供随机访问 并且容量有限。 2.1. 链表简介 链表(LinkedList) 虽然是

    2024年02月11日
    浏览(44)
  • 【数据结构】详解链表结构

    上篇博客已经介绍了顺序表的实现:【数据结构】详解顺序表。最后在里面也谈及了顺序表结构的缺陷,即 效率低,空间浪费 等等问题,那么为了解决这些问题,于是乎我们引入了链表的概念,下面将对链表结构进行讲解 首先肯定会问,到底什么是链表? 链表的概念 : 链

    2024年02月05日
    浏览(44)
  • 【数据结构】链表的回文结构

    单链表的操作算法是笔试面试中较为常见的题目。 本文将着重介绍平时面试中常见的关于链表的应用题目,马上要进行秋招了。希望对你们有帮助 _ 😀 对于一个链表,请设计一个时间复杂度为O(n),额外空间复杂度为O(1)的算法,判断其是否为回文结构。 给定一个链表的头指针

    2024年02月12日
    浏览(55)
  • 【数据结构】浅谈数据结构-链表【思路+例题学习】

    🏆今日学习目标: 🍀学习算法-数据结构-链表 ✅创作者:贤鱼 ⏰预计时间:30分钟 🎉个人主页:贤鱼的个人主页 🔥专栏系列:算法 🍁贤鱼的个人社区,欢迎你的加入 贤鱼摆烂团 链表是一种物理存储单元上非连续、非顺序的存储结构,数据元素的逻辑顺序是通过链表中

    2024年01月21日
    浏览(45)
  • 【数据结构】每天五分钟,快速入门数据结构(二)——链表

    目录 一 构建一个单向链表 二 特点 三 时间复杂度 四 相关算法 1.判断链表是否成环及成环位置 2.链表反转 五 Java中的LinkedList 类 1.使用 2.LinkedList 方法 长度无限 适合任意位置插入和删除频繁的场景 物理上可以不连续 访问、插入、删除 的时间复杂度均为O(n) 在头部插入元素

    2024年02月21日
    浏览(47)
  • 【数据结构】反转链表、链表的中间节点、链表的回文结构(单链表OJ题)

    正如标题所说,本文会图文详细解析三道单链表OJ题,分别为:  反转链表 (简单)  链表的中间节点 (简单)  链表的回文结构 (较难) 把他们放在一起讲的原因是:  反转链表 和  链表的中间节点 是  链表的回文结构 的基础 为什么这样说?请往下看: 目录 1. 反转链

    2024年02月13日
    浏览(72)

觉得文章有用就打赏一下文章作者

支付宝扫一扫打赏

博客赞助

微信扫一扫打赏

请作者喝杯咖啡吧~博客赞助

支付宝扫一扫领取红包,优惠每天领

二维码1

领取红包

二维码2

领红包