约瑟夫问题
(用new创建新的空间) 结构体(包含数据域和指针域)
#include<bits/stdc++.h>
using namespace std;
1.对于动态链表,由于是链式存储的,空间不一定是连续的,所以需要指针,定义一个动态链表的节点的一个结构体
//定义一个链表的节点:数据域data和node类型的指针next(存下一个节点的地址)
struct node{
int data;
node* next;
};
int main(){
//读入人数、需要查询的人的编号
int n,m;
scanf("%d%d",&n,&m);
2.创建动态链表,一般常用到的三个指针:head(记录头结点的地址)、now(记录目前链表的最后一个节点的地址)、p(用于创建新的节点的指针)
//定义指向节点的指针*head (记录头结点)*now(记录当前链表的最后一个节点)
//*p(用于创建新的节点) *pre(用于存第m个人的前一个节点的地址)
node* head,*now,*p,*pre;//不要忘记*
3.创建动态链表:(指定头节点的写法)
//用head节点new创建一个链表的头结点
//将head->data=1,head->next=NULL
//将*now指针取head的地址,表示当前链表的最后一个节点的地址
head=new node;
head->data =1;
head->next =NULL;
now=head;
//创建链表,从第2个节点开始一直添加到第n个节点
//用*p指针创建一个新的节点,将p->data=i,p->next=NULL
//再将新创建的节点与前面一个节点相连接(尾插法):now->next=p;
//再更新now为p
for(int i=2;i<=n;i++){
p=new node;
p->data =i;
p->next =NULL;
now->next =p;
now=p;
}
4.判断创建的链表是否需要首尾相连,形成循环链表
//最后由于链表是首尾相连的,所以让now->next=head;
now->next =head;
5.遍历整个链表,查询满足条件的节点,输出节点信息,删除节点,释放空间
由于进行增删操作,需要改变前后节点的指针的指向,所以需要一个指针*pre记录下进行修改的前一个节点的地址,由于需要输出需要查询的节点的信息,所以需要一个指针*now记录下需要进行修改的节点的地址。
再将前一个节点指向需要删除的节点的后一个节点,由于之前是用new开了新空间,所以现在由于删除了这个节点,就可以将这个节点的空间给释放掉了。
//进行数数
//先将now和pre取址head
now=head;pre=head;
//只要还有大于一个人,就继续循环
while((n--)>1){
//循环从1到m-1,每次先记录下当前的节点:pre=now
//再将now进行移动到下一个节点:now=now->next
//这样最后经过这个for循环之后now指向的是第m个节点,而pre是指向第m-1个节点
for(int i=1;i<m;i++){
pre=now;
now=now->next ;
}
//输出第m个节点的对应的人的编号
printf("%d ",now->data);
//输出之后跳过第m个节点:pre->next=now->pre
//第m个节点已经没用了,就可以将其delete掉了
pre->next =now->next ;
delete now;
//再进行下一轮:将now更新为pre->next;
now=pre->next ;
}
6.输出最后一个节点的信息后,将空间释放,这样由于每次删除一个节点,就将对应的空间释放掉了,所以最后链表所占的空间为0
//跳出while循环之后就只剩下一个节点,输出这个人的编号,
//再释放最后一个节点的内存空间
printf("%d",now->data );
delete now;
return 0;
}
插排
(用malloc创建动态链表)(结构体包含数据域和指针域)
题目描述
AC代码:
#include<stdlib.h>
1.对于动态链表,由于是链式存储的,空间不一定是连续的,所以需要指针,定义一个动态链表的节点的一个结构体
/*由于要用创建动态的单向链表,所以需要用到指针,定义一个结构体:
用于表示链表的一个节点*/
struct node{
int data;
struct node *next;
};
int main(){
2.创建动态链表需要三个基本的指针:*head,*now, *p
//对于一个动态链表来说:通常来说有至少4个节点指针:
/* struct node *head(用来存链表的头结点的地址),*now(用于记录当前链表的最后一个节点),*p(用于创建新的节点),*t(获得链表的首地址,用于后期的遍历链表)*/
3.创建动态链表(用malloc开新的空间)(没有固定头结点的写法)
struct node *head=NULL;
struct node *now,*p;
/*这个链表需要存多少个节点就进行几次循环,每次循环创建用malloc创建一个新的节点,将节点对应的数据域存入,每个新的节点的指针指向NULL
判断一下如果是head=NULL即表示当前新创的节点就是链表的头结点,所以将该节点的地址赋给head
否则就将now指向刚刚新创的节点,之后由于为了进行尾插,所以更新now的值*/
for(int i=1;i<=10;i++){
int x;
scanf("%d",&x);
p=(struct node*)malloc(sizeof(struct node));
p->data=x;
p->next=NULL;
if(head==NULL){
head=p;
}else{
now->next=p;
}
//注意由于无论新创建的节点是不是新的节点,链表的最后一个节点都得到了更新,所以now要更新为新创的这个节点p,注意该语句存放的位置
now=p;
}
int m;
scanf("%d",&m);
struct node *t=head;
4.遍历整个链表,找到指定位置的节点,在两个节点间插入一个新的节点
/*注意对于在链表中的某两个节点进行插入一个节点的方法:
1.先要遍历整个链表:1获取头结点的地址2.循环条件!=NULL 3.迭代的语句:t=t->next
2.由于插入一个节点,需要改变的的是该节点之前的和本节点的next指针,所以先要根据查询的条件找到前一个节点的位置pre和后一节点的位置
3.再创建一新的节点,填入节点的信息
4.将该新节点指向pre的下一个节点,将pre指向新创建的节点*/
while(t!=NULL){
if(t->next->data>m){
p=(struct node*)malloc(sizeof(struct node));
p->data=m;
p->next=t->next;
t->next=p;
break;
}
t=t->next;
}
**5.遍历整个链表**
/*想要遍历整个表:
1.先获得这个表的首地址 2.在设置while循环的条件(t!=NULL),就进入循环执行循环体中的内容,不要忘记要让t一个一个不断向后一个节点移动,否则会进入死循环*/
2.For(struct node *t=head;t!=NULL;t=t->next)
t=head;
while(t!=NULL){
printf("%d ",t->data);
t=t->next ;
}
return 0;
}