【数据结构】实验三:链表
实验三链表
一、实验目的与要求
1)熟悉链表的类型定义;
2)熟悉链表的基本操作;
3)灵活应用链表解决具体应用问题。
二、实验内容
1)请设计一个单链表的存储结构,并实现单链表中基本运算算法。
编写程序linklist.cpp实现单链表的各种基本运算(假设单链表元素类型ElemType为char),并在此基础上设计主程序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后添加一个元素valvoid 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;*/
相关文章:

【数据结构】实验三:链表
实验三链表 一、实验目的与要求 1)熟悉链表的类型定义; 2)熟悉链表的基本操作; 3)灵活应用链表解决具体应用问题。 二、实验内容 1)请设计一个单链表的存储结构,并实现单链表中基本运算算…...

第4集丨webpack 江湖 —— loader的安装和使用
目录 一、loader简介1.1 使用 loader1.1.1 配置文件方式1.1.2 内联方式 1.2 loader 特性1.3 解析 loader1.4 命名规范 二、css loader的安装和使用2.1 安装2.2 配置2.3 测试 三、 less-loader 的安装和使用3.1 安装3.2 配置3.3 测试3.4 附件3.4.1 webpack.config.js3.4.2 index…...

【Lua学习笔记】Lua进阶——协程
文章目录 协程协程的定义和调度StatusRunning 协程 协程是一种并发操作,相比于线程,线程在执行时往往是并行的,并且线程在创建销毁执行时极其消耗资源,并且过长的执行时间会造成主进程阻塞。而协程可以以并发时轮值时间片来执行&…...

亚马逊云科技纽约峰会,充分释放数据价值和生成式AI的潜力
生成式AI将深刻改变每个公司的运营方式,标志着人工智能技术发展的新转折点。亚马逊云科技昨日在纽约峰会上宣布,推出七项生成式AI新功能,进一步降低了生成式AI的使用门槛,让无论是业务用户还是开发者都能从中受益。借助这些新功能…...

什么是 web3?
在百度搜索引擎输入 “Web3”、“大厂”。跳出来基本都是这样的标题. 以及如今的互联网行业 “哀鸿遍野”,不仅内卷,还裁员。然后掀起一阵风,猛吹 Web3 的好,数据回归用户……最后再 “威逼利诱” 一下,Web3 就是 20 年…...

[驱动开发]字符设备驱动应用——点灯
点亮开发板stm32mp157的三盏灯 //头文件 #ifndef __LED_H__ #define __LED_H__//封装GPIO寄存器 typedef struct { volatile unsigned int MODER; // 0x00volatile unsigned int OTYPER; // 0x04volatile unsign…...

前端学习——Vue (Day5)
自定义指令 <template><div><h1>自定义指令</h1><input v-focus ref"inp" type"text" /></div> </template><script> export default {// mounted(){// this.$ref.inp.focus()// }// 2. 局部注册指令di…...

Ceph版本
每个Ceph的版本都有一个英文的名称和一个数字形式的版本编号 第一个 Ceph 版本编号是 0.1,发布于2008 年 1月。之后是0.2,0.3....多年来,版本号方案一直没变。 2015年 4月0.94.1 (Hammer 的第一个修正版) 发布后,为了避免 0.99 (以及 0.100…...

cspm是什么?考了有用吗?
CSPM是项目管理专业人员能力评价等级证书,相当于 PMP 的本土化,CSPM 相关问题大家都很关心,今天就给大家全面解答一下 CSPM到底是何方神圣? 文章主要是解答下面几个常见问题,其他问题可以留言或者私信咨询我哦~ 一、什…...

Java阶段五Day14
Java阶段五Day14 文章目录 Java阶段五Day14分布式事务整合demo案例中架构,代码关系发送半消息本地事务完成检查补偿购物车消费 鲁班周边环境调整前端启动介绍启动前端 直接启动的项目gateway(网关)login(登录注册)atta…...

【计算机网络】应用层协议 -- 安全的HTTPS协议
文章目录 1. 认识HTTPS2. 使用HTTPS加密的必要性3. 常见的加密方式3.1 对称加密3.2 非对称加密3.3 非对称加密对称加密 4. 引入CA证书4.1 CA认证4.2 数据签名4.3 非对称机密对称加密证书认证4.4 常见问题 5. 总结 1. 认识HTTPS HTTPS全称为 Hyper Text Tranfer Protocol over …...

小程序通过ip+port+路径获取服务器中的图片
配置IIS 首先需要配置IIS。 打开控制面板,接下来的流程按下图所示。 安装好后,按“win”键,搜索IIS 选择一个ip地址,或手动填写,端口号按需更改...

Codeforces Round 888 (Div. 3)(A-F)
文章目录 ABCDEF A 题意: 就是有一个m步的楼梯。每一层都有k厘米高,现在A的身高是H,给了你n个人的身高问有多少个人与A站在不同层的楼梯高度相同。 思路: 我们只需要去枚举对于A来说每一层和他一样高(人的身高和楼…...

【人工智能】深度神经网络、卷积神经网络(CNN)、多卷积核、全连接、池化
深度神经网络、卷积神经网络(CNN)、多卷积核、全连接、池化) 文章目录 深度神经网络、卷积神经网络(CNN)、多卷积核、全连接、池化)深度神经网络训练训练深度神经网络参数共享卷积神经网络(CNN)卷积多卷积核卷积全连接最大池化卷积+池化拉平向量激活函数优化小结深度神经…...

失去SSL证书,会对网站安全造成什么影响?
作为网络世界中的“身份证”,SSL证书可以在网络世界中证明你是一个真实可信的企业或个人网站,而不是一个钓鱼网站。且在网站的服务器上部署SSL证书后,可以使网站与访问者之间通过SSL协议建立安全的加密连接,确保在Web服务器和浏览…...

gitee中fork了其他仓库,如何在本地进行同步
GitHub 操作:同步 Fork 来的仓库(上游仓库)_sigmarising的博客-CSDN博客 1. 设置upstream 2. git pull --rebase 3. 然后再执行pull、push操作...

java项目之社区生活超市管理系统(ssm+mysql+jsp)
风定落花生,歌声逐流水,大家好我是风歌,混迹在java圈的辛苦码农。今天要和大家聊的是一款基于ssm的社区生活超市管理系统。技术交流和部署相关看文章末尾! 开发环境: 后端: 开发语言:Java 框…...

WebGPU(七):C++头部封装
WebGPU(七):C头部封装 在前面的学习中,我们使用的都是原生态的WebGPU API,那是基于C语言的API,但是为了更高效的开发,我们可以使用一个基于C的库。 根据参考的教程,这个github库提供更加纤细的描述。它提…...

Linux 网络通信epoll详解( 10 ) -【Linux通信架构系列 】
系列文章目录 C技能系列 Linux通信架构系列 C高性能优化编程系列 深入理解软件架构设计系列 高级C并发线程编程 期待你的关注哦!!! 现在的一切都是为将来的梦想编织翅膀,让梦想在现实中展翅高飞。 Now everything is for the…...

java源码-List源码解析
Java中的List是一个接口,它定义了一组操作列表的方法。List接口的常见子类包括ArrayList、LinkedList和Vector等。 以下是Java中List接口及其常见方法的源码解析: 1. List接口定义 public interface List<E> extends Collection<E> { …...

Mybatis的动态SQL
动态 sql 是Mybatis的强⼤特性之⼀,能够完成动态的 sql 语句拼接。 动态 SQL 大大减少了编写代码的工作量,更体现了 MyBatis 的灵活性、高度可配置性和可维护性。 Mybatis里的动态标签主要有: <if><trim><where><set><forea…...

嵌入式系统中的GPIO控制:从理论到实践与高级应用
本文将探讨嵌入式系统中的GPIO(通用输入输出)控制,着重介绍GPIO的原理和基本用法。我们将使用一个实际的示例项目来演示如何通过编程配置和控制GPIO引脚。将基于ARM Cortex-M微控制器,并使用C语言进行编写。 GPIO是嵌入式系统中最常见且功能最强大的接口之一。它允许硬件工…...

7D透明屏的市场应用广泛,在智能家居中有哪些应用表现?
7D透明屏是一种新型的显示技术,它能够实现透明度高达70%以上的显示效果。这种屏幕可以应用于各种领域,如商业广告、展览展示、智能家居等,具有广阔的市场前景。 7D透明屏的工作原理是利用光学投影技术,将图像通过透明屏幕投射出来…...

[游戏开发][Unity] 打包Xcode工程模拟器+真机调试
苹果开发者账号 账号分三类,个人,公司,企业,价格99/99/299美金 新注册账号的基本设置按网上的教程来就行 我们公司是企业账号,我的苹果开发者账号是公司一个User 下面讲述一下一个全新的打包机处理流程 首先是要把…...

python 添加环境变量
1 查看是否设置环境变量 和 使用的python在哪里安装 import sys import os# 获取Python的安装目录 import os import syspython_path sys.executable # 这个是python.exe的路径python_path os.path.dirname(python_path) print("Python安装路径:", python_path)# …...

如何用DHTMLX组件为Web应用创建甘特图?(一)
dhtmlxGantt是用于跨浏览器和跨平台应用程序的功能齐全的Gantt图表。可满足项目管理应用程序的所有需求,是最完善的甘特图图表库。甘特图仍然是项目管理应用程序中最需要的工具之一,DHTMLX Gantt组件提供了能提升研发甘特图功能所需的重要工具。 在这篇…...

网站SEO优化:提升搜索排名与流量引爆
导言: 在互联网时代,网站SEO(搜索引擎优化)是提高网站搜索排名、吸引流量、增加曝光的重要策略。通过优化网站结构、内容和链接等方面,让搜索引擎更好地理解和收录网站内容,从而为网站带来更多有价值的有机…...

Java lamda对List<JSONObject>里多个动态属性字段进行动态的降序或者升序
最近做到一个需求,需要把业务侧返回的数据(格式为List<JSONObject>),然后根据前端传来的排序字段、以及升降序属性来排序并返回给前端。要对List<JSONObject>中的多个属性字段进行动态的升序或降序排序,我们可以根据需…...

Lua脚本解决多条命令原子性问题
Redis是一个流行的键值存储数据库,它提供了丰富的功能和命令。在Redis中,我们可以使用Lua脚本来编写多条命令,以确保这些命令的原子性执行。Lua是一种简单易学的编程语言,下面将介绍如何使用Redis提供的调用函数来操作Redis并保证…...

NAT详解(网络地址转换)
一句话说清楚它是干什么的: 网络地址转换:是指通过专用网络地址转换为公用地址,从而对外隐藏内部管理的IP地址,它使得整个专用网只需要一个全球IP就可以访问互联网,由于专用网IP地址是可以重用的,所以NAT大…...