文章目录
一、前言
二、循环单链表每次循环删除一个最小的
每次删除最小数值data节点,两层循环,外层循环用于遍历整个链表,因为是循环链表,退出条件是str1->next!=str1,内层循环不断寻找当前链表中比自己更小的值,并将其与其前缀(用于删除)记录下来,最后出内层循环后删除
#include <iostream>
#include <stdlib.h>
#include<stdio.h>
using namespace std;
typedef struct node {
int data;
struct node *next;
}Node,*Linklist;
//查找类 加一个删除操作 变成了删除类 循环单链表
void myfunction(Linklist str1){
Linklist p,pre,pmin,premin;
while(str1->next!=str1){
//单链循环
p=str1->next;pre=str1;
pmin=p;premin=pre;
while(p!=str1){
//单链循环
if(p->data<pmin->data){
pmin=p;
premin=pre;
}
pre=p;
p=p->next;
}
cout<<"当前删去的节点的数值为: ";
cout<<pmin->data<<endl;
premin->next=pmin->next;
free(pmin);
cout<<"删除后遍历: ";
Linklist pa=str1->next;
while(pa!=str1){
cout<<pa->data;
pa=pa->next;
}
cout<<endl;
cout<<endl;
}
free(str1);
}
int main()
{
int a[5];
for (int i=0;i<5;i++)
cin>>a[i];
Linklist first=new Node;
first->next=first;
for (int i=0;i<5;i++){
//单链循环也使用头插 记住
Linklist s=new Node;
s->data=a[i];
s->next=first->next;
first->next=s;
}
Linklist p=first->next;
cout<<"当前列表为: ";
while(p!=first){
//循环链表都是这样 非循环链表 p!=NULL
cout<<p->data;
p=p->next;
}
cout<<endl;
myfunction(first);
return 0;
}
运行结果:
循环单链表每次循环删除一个最小的
三、单链表每次循环删除一个最小的
每次删除最小数值data节点,两层循环,外层循环用于遍历整个链表,因为是非循环链表,退出条件是str1->next!=NULL,内层循环不断寻找当前链表中比自己更小的值,并将其与其前缀(用于删除)记录下来,最后出内层循环后删除
#include <iostream>
#include<stdlib.h>
#include<stdio.h>
using namespace std;
typedef struct node {
int data;
struct node * next;
}Node,*Linklist;
//本来查找类 添加了一个删除操作 就变成了删除类
void myfunction(Linklist str1){
Linklist p,pre,minp,minpre;
while(str1->next!=NULL){
//非循环
p=str1->next;pre=str1;
minp=p;minpre=pre;
while(p){
//非循环
if(p->data<minp->data){
minp=p;
minpre=pre;
}else {
pre=p;
p=p->next;
}
}
cout<<"当前删去的节点的数值为: ";
cout<<minp->data<<endl;
minpre->next=minp->next;
free(minp);
cout<<"删除后遍历: ";
Linklist pa=str1->next;
while(pa){
cout<<pa->data;
pa=pa->next;
}
cout<<endl;
cout<<endl;
}
free(str1);
}
int main()
{
int a[5];
for (int i=0;i<5;i++)
cin>>a[i];
Linklist first=new Node;
Linklist r=first;
for (int i=0;i<5;i++){
Linklist s=new Node;
s->data=a[i];
r->next=s;
r=s;
}
r->next=NULL;
Linklist p=first->next;
cout<<"当前列表为: ";
while(p){
cout<<p->data;
p=p->next;
}
cout<<endl;
myfunction(first);
return 0;
}
运行结果:
单链表每次循环删除一个最小的
四、循环双链表每次循环删除一个最小的
每次删除最小数值data节点,两层循环,外层循环用于遍历整个链表,因为是循环链表,退出条件是str1->next!=str1,内层循环不断寻找当前链表中比自己更小的值,并将其与其前缀(用于删除)记录下来,最后出内层循环后删除(注意,双链表的删除要同时修改prior和next指针)
#include <iostream>
#include<stdlib.h>
#include<stdio.h>
using namespace std;
//循环双链表 中删除元素
typedef struct node {
int data;
struct node *next;
struct node *prior;
}Node,*Linklist;
void myfunction(Linklist str1){
Linklist p,pre,minp,minpre;
while(str1->next!=str1){
//循环链表
p=str1->next;pre=str1;
minp=p;minpre=pre;
while(p!=str1){
//循环链表
if (p->data<minp->data){
minp=p;
minpre=pre;
}else {
pre=p;
p=p->next;
}
}
cout<<"要删除的元素为:"<<endl;
cout<<minp->data<<endl;
cout<<"删除前遍历1"<<endl;
Linklist pa=str1->next;
while(pa!=str1){
cout<<pa->data;
pa=pa->next;
}
cout<<endl;
pa=str1->prior;
while(pa!=str1){
cout<<pa->data;
pa=pa->prior;
}
cout<<endl;
//双链表中删除一个元素 good 插入 单链表和单链循环表中插入相同 双链表插入比双链循环中多一个判断
//删除 单链表和单链循环表删除相同 双链表和双链循环删除相同
minp->prior->next=minp->next;
minp->next->prior=minp->prior;
free(minp);
cout<<"删除后遍历1"<<endl;
pa=str1->next;
while(pa!=str1){
cout<<pa->data;
pa=pa->next;
}
cout<<endl;
pa=str1->prior;
while(pa!=str1){
cout<<pa->data;
pa=pa->prior;
}
cout<<endl;
}
free(str1);
}
int main()
{
int a[5];
for (int i=0;i<5;i++)
cin>>a[i];
Linklist first=new Node;
first->next=first->prior=first;
for (int i=0;i<5;i++){
Linklist s=new Node;
s->data=a[i];
s->next=first->next;
s->prior=first;
first->next->prior=s;
first->next=s;
}
Linklist p=first->next;
while(p!=first){
//循环遍历
cout<<p->data;
p=p->next;
}
cout<<endl;
myfunction(first);
return 0;
}
运行结果:
因为是双链表,所以输出中打印正序(next指针)和逆序(prior指针)两种形式,让读者可以看得更明白
五、双链表每次循环删除一个最小的
每次删除最小数值data节点,两层循环,外层循环用于遍历整个链表,因为是非循环链表,退出条件是str1->next!=NULL,内层循环不断寻找当前链表中比自己更小的值,并将其与其前缀(用于删除)记录下来,最后出内层循环后删除
#include <iostream>
#include<stdlib.h>
#include<stdio.h>
using namespace std;
typedef struct node {
int data;
struct node *next;
struct node *prior;
}Node,*Linklist;
void myfunction(Linklist str1){
Linklist p,pre,minp,minpre;
while(str1->next!=NULL){
//非循环链表
p=str1->next;pre=str1;
minp=p;minpre=pre;
while(p){
if(p->data<minp->data){
minp=p;
minpre=pre;
}else {
pre=p;
p=p->next;
}
}
cout<<"要删除的元素"<<endl;
cout<<minp->data<<endl;
cout<<"删除前遍历"<<endl;
Linklist pa=str1->next;
while(pa){
cout<<pa->data;
pa=pa->next;
}
cout<<endl;
Linklist ra=str1;
while(ra->next!=NULL){
ra=ra->next;
}
while(ra!=str1){
//反向输出注意不要有str1
cout<<ra->data;
ra=ra->prior;
}
cout<<endl;
//双链非循环插入和删除都要判断
if(minp->prior!=NULL)
minp->prior->next=minp->next;
if(minp->next!=NULL)
minp->next->prior=minp->prior;
free(minp);
cout<<"删除后遍历"<<endl;
pa=str1->next;
while(pa){
cout<<pa->data;
pa=pa->next;
}
cout<<endl;
ra=str1;
while(ra->next!=NULL){
ra=ra->next;
}
while(ra!=str1){
//反向输出注意不要有str1
cout<<ra->data;
ra=ra->prior;
}
cout<<endl;
}
free(str1);
}
int main()
{
int a[5];
for (int i=0;i<5;i++)
cin>>a[i];
Linklist first=new Node;
first->next=first->prior=NULL;
for (int i=0;i<5;i++){
Linklist s=new Node;
s->data=a[i];
s->next=first->next;
s->prior=first;
if(first->next!=NULL)
first->next->prior=s;
first->next=s;
}
cout<<"正序遍历:";
Linklist p=first->next;
while(p){
//非循环
cout<<p->data;
p=p->next;
}
cout<<endl;
cout<<"逆序遍历:";
Linklist ra=first;
while(ra->next!=NULL){
ra=ra->next;
}
p=ra;
while(p!=first){
//反向遍历 双链非循环一定要找到尾巴 双链循环不需要 插入和遍历 双链非循环才是最麻烦的 删除和双链循环一样
cout<<p->data;
p=p->prior;
}
cout<<endl;
myfunction(first);
return 0;
}
运行结果:
六、循环双链表记录访问次数,按访问次数排序
在双链循环链表中,添加一个freq域,记录结点被访问的次数,每次输出按被访问的次数排序,被访问次数相同则最近被访问的排在前面
#include <iostream>
#include<stdlib.h>
#include<stdio.h>
using namespace std;
typedef struct node {
int data;
int freq;
struct node *next;
struct node *prior;
}Node,*Linklist;
void myfunction2(Linklist str1,int x){
Linklist pa=str1->next,q;
while(pa!=str1&&pa->data!=x)//循环 pa!=str1 非循环 pa
pa=pa->next;
if(pa==NULL)
return;
else{
pa->freq++;
//删除
pa->next->prior=pa->prior;
pa->prior->next=pa->next;
q=pa->prior;//要向前移动
while(q!=str1&&q->freq<=pa->freq)//按照freq排序 这里不是data
q=q->prior;
//插入
pa->next=q->next;
pa->prior=q;
q->next->prior=pa;
q->next=pa;
}
}
int main()
{
int a[5];
for (int i=0;i<5;i++){
cin>>a[i];
}
Linklist first=new Node;
first->next=first->prior=first;
for (int i=0;i<5;i++){
Linklist s=new Node;
s->data=a[i];
s->freq=0;
s->next=first->next;
s->prior=first;
first->next->prior=s;
first->next=s;
}
Linklist p=first->next;
while(p!=first){
//循环
cout<<p->data;
p=p->next;
}
cout<<endl;
while(true){
int n;
cin>>n;
myfunction2(first,n);
p=first->next;
while(p!=first){
//循环
cout<<p->data;
cout<<" ";
cout<<p->freq<<endl;
p=p->next;
}
cout<<endl;
}
return 0;
}
运行结果:
先通过while找到pa结点的位置,然后将它的freq++,然后将它从双链循环链表中摘除,然后再找到合适的位置(结点间按freq排序),将其插入链表
七、双链表记录访问次数,按访问次数排序
在双链非循环链表中,添加一个freq域,记录结点被访问的次数,每次输出按被访问的次数排序,被访问次数相同则最近被访问的排在前面。
#include <iostream>
#include<stdio.h>
#include<stdlib.h>
using namespace std;
//freq;
typedef struct node {
int data;
int freq;
struct node *next;
struct node *prior;
}Node,*Linklist;
Linklist myfunction(Linklist str1,int x){
Linklist pa=str1->next,q;
while(pa&&pa->data!=x)
pa=pa->next;
if(pa==NULL){
return NULL;
}else{
//找到了 freq++
pa->freq++;
//摘取pa然后再加上去
if(pa->next!=NULL) //插入删除查找 双链表都比双链循环链表要麻烦 插入删除要判断 遍历要确定尾节点
pa->next->prior=pa->prior;
if(pa->prior!=NULL)
pa->prior->next=pa->next;
q=pa->prior;
while(q!=str1&&q->freq<=pa->freq)
q=q->prior;
pa->next=q->next;
pa->prior=q;
q->next->prior=pa;
q->next=pa;
}
return pa;//为什么这里返回pa 而不是返回str1 返回x节点的指针
}
int main()
{
int a[5];
for (int i=0;i<5;i++)
cin>>a[i];
Linklist first=new Node;
first->next=first->prior=NULL;
for (int i=0;i<5;i++){
Linklist s=new Node;
s->data=a[i];
s->freq=0;
s->next=first->next;;
s->prior=first;
if(first->next!=NULL)
first->next->prior=s;
first->next=s;
}
Linklist p=first->next;
while(true){
int n;
cin>>n;
myfunction(first,n);
//输出
p=first->next;
while(p){
//非循环
cout<<p->data;
cout<<" ";
cout<<p->freq<<endl;
p=p->next;
}
}
return 0;
}
运行结果:
先通过while找到pa结点的位置,然后将它的freq++,然后将它从双链循环链表中摘除,然后再找到合适的位置(结点间按freq排序),将其插入链表
八、小结
单链表第四篇,完成了。
四种链表删去最小元素,一个个删除;
然后,循环双链表和非循环双链表,记录访问次数,并按访问次数排序。
天天打码,天天进步!!!