【数据结构】单链表第四篇

一、前言

二、循环单链表每次循环删除一个最小的

每次删除最小数值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排序),将其插入链表

八、小结

单链表第四篇,完成了。

四种链表删去最小元素,一个个删除;
然后,循环双链表和非循环双链表,记录访问次数,并按访问次数排序。

天天打码,天天进步!!!

猜你喜欢

转载自blog.csdn.net/qq_36963950/article/details/109005583
今日推荐