双链表的创建与输出:
#include<cstdio>
using namespace std;
struct node
{int data; //data记录这个结点对应元素的值node *next,*pre; //next指向后继 pre指向前驱
}*head,*tail,*p;
int n,k;
int main()
{scanf("%d",&n);head=new node;head->pre=head->next=NULL;tail=head; //新建一个虚拟头结点(不储存元素的值)//方便删除操作(不会越界),此时头尾指针都指向他for(int i=1;i<=n;++i) {p=new node;scanf("%d",&p->data);//输入第n个元素的值,储存到新建的结点中 p->pre=tail;tail->next=p; //将p指向的节点插入到tail指向的结点的后面 p->next=NULL;tail=p; //将tail更新为p,下次就插入在它的后面 }p=new node;p->pre=tail;p->next=NULL;tail->next=p;tail=p; //和虚拟头结点类似,建立虚拟尾结点//方便删除和查询、输出p=head->next; //p指向虚拟头结点的后继,即第一个元素 while(p!=tail) //遍历到虚拟尾结点时停止{printf("%d ",p->data);//输出该结点的元素 p=p->next;} return 0;
}
双链表插入结点:
#include<cstdio>
#include<iostream>
using namespace std;
struct node
{int data; //data记录这个结点对应元素的值node *next,*pre; //next指向后继 pre指向前驱
}*head,*tail,*p;
void insert(node *head,int i,int x) //在双向链表的第i个结点之前插入x
{node *s,*p; //node型指针*s,*p; int j; //定义计数器j s=new node; //申请新结点s,用于存储插入的数据 s->data=x; //为s->data ,数据域赋值为x p=head; //给p赋值为head j=0; //计数器赋初值为0 while((p->next!=NULL)&&(j<=i)) {p=p->next;j++;} //p指向第i个结点if(p->next==NULL) printf("no this position!\n");else{ //将结点s插入到结点p之前 p->pre->next=s; //将p的本来前趋结点的后继指向ss->pre=p->pre;//将s的前趋指向p的前趋p->pre=s; //将s作为p的新前趋s->next=p; //将s的后继指向p }
}
int n,x,y;
int main()
{scanf("%d",&n);head=new node;head->pre=head->next=NULL;tail=head; //新建一个虚拟头结点(不储存元素的值)//方便删除操作(不会越界),此时头尾指针都指向他for(int i=1;i<=n;++i) {p=new node;scanf("%d",&p->data);//输入第n个元素的值,储存到新建的结点中 p->pre=tail;tail->next=p; //将p指向的节点插入到tail指向的结点的后面 p->next=NULL;tail=p; //将tail更新为p,下次就插入在它的后面 }p=new node;p->pre=tail;p->next=NULL;tail->next=p;tail=p; //和虚拟头结点类似,建立虚拟尾结点//方便删除和查询、输出scanf("%d%d",&x,&y);insert(head, x, y);p=head->next; //p指向虚拟头结点的后继,即第一个元素 while(p!=tail) //遍历到虚拟尾结点时停止{printf("%d ",p->data);//输出该结点的元素 p=p->next;} return 0;
}
双链表删除第K个结点:
#include<cstdio>
#include<iostream>
using namespace std;
struct node
{int data; //data记录这个结点对应元素的值node *next,*pre; //next指向后继 pre指向前驱
};
node *get(node *head,int n)//寻找第n个结点
{node *p=head;for(int i=1;i<=n;i++){if(p==NULL){break;}p=p->next;}return p;
}
void remove(node *head,int n)
{node *p=get(head,n) ;//寻找第n个结点 if(p==NULL) //判断是否存在第n个结点 {cout<< "no this position!"<<endl;return;}else {p->pre->next=p->next; //将k结点的前趋结点的next指向k结点的后继结点 p->next->pre=p->pre; //将k结点的后继结点的pre指向k结点的前趋结点 delete p ; //释放k结点 }
} int main()
{node *head,*tail,*p;int n,k;scanf("%d",&n);head=new node;head->pre=head->next=NULL;tail=head; //新建一个虚拟头结点(不储存元素的值)//方便删除操作(不会越界),此时头尾指针都指向他for(int i=1;i<=n;++i) {p=new node;scanf("%d",&p->data);//输入第n个元素的值,储存到新建的结点中 p->pre=tail;tail->next=p; //将p指向的节点插入到tail指向的结点的后面 p->next=NULL;tail=p; //将tail更新为p,下次就插入在它的后面 }p=new node;p->pre=tail;p->next=NULL;tail->next=p;tail=p; //和虚拟头结点类似,建立虚拟尾结点//方便删除和查询、输出scanf("%d",&k);remove(head,k);p=head->next; //p指向虚拟头结点的后继,即第一个元素 while(p!=tail) //遍历到虚拟尾结点时停止{printf("%d ",p->data);//输出该结点的元素 p=p->next;} return 0;
}
约瑟夫问题:单循环链表
#include<iostream>
using namespace std;
struct node
{int data;node *next;
};
int n,m;
node *head,*tail,*p;
int main()
{int i,j,k,l;cin>>n>>m;head=new node;head->data=1;head->next=NULL;tail=head; //将头尾结点都指向1for(i=2;i<=n;i++) {p=new node;p->data=i;p->next=NULL;tail->next=p;tail=p;} //建立链表tail->next=head;tail=head; //单链表头尾相连,成为循环单链表for(i=1;i<=n;i++) {for(j=1;j<=m-2;j++)tail=tail->next;cout<<tail->next->data<<" ";tail->next=tail->next->next;tail=tail->next;}return 0;
}
约瑟夫问题:双向循环链表
#include<cstdio>
using namespace std;
struct node
{int data; //记录这个结点对应的编号node *next,*pre; //next 指向结点的后继, pre指向结点的先驱
}*head,*tail,*p; //head表示头结点 tail表示尾结点
int n,m;
int main()
{scanf("%d%d",&n,&m);head=new node;head->data=1;head->next=head->pre=NULL;tail=head; //先建立编号为1的结点,头指针和尾指针都指向它for(int i=2;i<=n;++i){p=new node;p->data=i; //建立编号为i的结点tail->next=p; //将p指向的结点 插入到tail指向的结点 后面p->pre=tail;p->next=NULL;tail=p; //将tail更新为p,下次就插入在它的后面 }head->pre=tail;tail->next=head; //因为是循环列表,所以头尾相连p=head;for(int i=1;i<=n;++i) //需要按照顺序删除n-1 个结点{for(int j=1;j<m;++j) //找到需要删除的结点 p=p->next;printf("%d ",p->data); //输出值 p->next->pre=p->pre; //删除结点 p->pre->next=p->next;p=p->next; //从下一个重新报数 }
}
约瑟夫问题:数组模拟链表
#include<iostream>
using namespace std;
const int N=100;
int a[N+1]; //a[i]表示第i号人的下一人的编号
int main()
{int n,m;cin>>n>>m;for(int i=1;i<n;i++) //建立数组模拟链表{a[i]=i+1;} a[n]=1; //建立数组模拟循环链表 第n人指向1,形成一个环int pre=n; // 前一人 int cur=1; // 当前人for (int p=0;p<n;p++) //n个人均出队为止{for(int k=1;k<m;k++) //报数计数器加一{pre=cur; //前一人变成当前人cur=a[pre];//当前人变成下一人 } cout<<cur<<" "; //数到m此人出队 a[pre] =a[cur]; //前一个人的下一个人变成当前人的下一人a[cur] =0; //当前人的下一人变成0cur=a[pre] ; //当前人变成当前的下一个人 } return 0;
}
约瑟夫问题:一维数组
#include<iostream>
using namespace std;
const int N=100;
bool a[N+1]; //初始为false
int main()
{int n,m,f=0,t=0,s=0;//f出圈的人数,t圈中位置编号,s为计数器cin>>n>>m;do{t++;//枚举圈中每个人 if(t==n+1) //数组模拟环状{t=1;} if(!a[t]) //t的位置有人报数{s++;} if(s==m) //当前报的数是m{s=0; //计数器清0cout<<t<<" " ; //输出出圈人的编号a[t] =true; //标记已经出局f++; //出局的人增加一个 } }while(f!=n); //全部出局为止 return 0;
}