2-1 A - 数据结构实验之链表一:顺序建立链表
#include
#include
typedef struct Node//typedef使用后,下面的结构体可不用struct
{
int data;
struct Node *next;
}node;
node *creat(int n)
{
node *head,*p,*tail;
head=(node*)malloc(sizeof(node));//malloc函数,建立一个头节点;
head->next=NULL;//头节点指向空;
tail=head;//尾节点指向空;
for(int i=0;idata);//给节点p赋值;
p->next=NULL;//p指向空;
tail->next=p;//让tail指向p;
tail=p;//将p代替tail的位置进行循环,可以实现将新的p顺序加到链表中;
}//顺序建链表;
return head;
}
int main()
{
node *head,*p;
int n;
scanf("%d",&n);
head=creat(n);//顺序建链表;
p=head->next;//遍历链表;
while(p)//也可以写while(p!=NULL)
{
if(p->next==NULL)
printf("%d",p->data);
else printf("%d ",p->data);
p=p->next;
}//输出;
return 0;
}
2-2 B - 数据结构实验之链表二:逆序建立链表
#include
#include
typedef struct Node
{
int data;
struct Node *next;
}node;
node *creat(int n)
{
node *head,*p;
head=(node*)malloc(sizeof(node));
head->next = NULL;//和顺序一样;
for(int i=0;idata);
p->next=head->next;//让p指向head所指的;
head->next=p;//让head指向p,实现将p逆序建立链表。
}
return head;
}
int main()
{
int n;
scanf("%d",&n);
node *head,*p;
head=creat(n);
p=head->next;
while(p)
{
if(p->next==NULL)
printf("%d",p->data);
else printf("%d ",p->data);
p=p->next;
}
return 0;
}
2-3 C - 师--链表的结点插入
#include
#include
typedef struct Node
{
int data;
struct Node *next;
}node;
void Insert(node *head,int m,int x)//执行插入操作的函数
{
node *q=(node *)malloc(sizeof(node)),*p=head;
q->data=x;//准备好新节点并赋值
for(int i=0;inext!=NULL;i++)//查找第m个,但如果p->next==NULL也要结束循环
{
p=p->next;//建立链表往后走
}
q->next=p->next;//将q插入找到的位置
p->next=q;
}
int main()
{
int n;
while(~scanf("%d",&n))
{
node *head,*p;
head=(node*)malloc(sizeof(node));
head->next=NULL;
for(int i=0; inext;
while(p)
{
if(p->next==NULL)
printf("%d\n",p->data);
else
printf("%d ",p->data);
p=p->next;
}
}
return 0;
}
2-4 D - 数据结构实验之链表七:单链表中重复元素的删除
#include
#include
typedef struct Node
{
int data;
struct Node *next;
}node;
node *creat(int n)//逆序建表
{
node *head,*p;
head=(node*)malloc(sizeof(node));
head-> next = NULL;
for(int i=0; idata);
p->next=head->next;
head->next=p;
}
return head;
}
void pri(node *p)//输出函数。这个记住,套公式几乎每个题都可以用
{
while(p)
{
if(p->next==NULL)
printf("%d\n",p->data);
else
printf("%d ",p->data);
p=p->next;
}
}
int main()
{
int n;
scanf("%d",&n);
node *head,*p;
head=creat(n);
printf("%d\n",n);
pri(head->next);
//下面是删除重复数据
node *q,*k;//q作为p的跟随结点用于删除操作,k用于遍历前面不重复部分的链表来判断p是否重复
p=head->next;
q=head;
while(p)
{
int flag=1;
k=head->next;
while(k!=p)
{
if(k->data==p->data)
{
flag=0;
n--;
q->next=p->next;
p=p->next;
break;
}
k=k->next;
}
if(flag==1)
{
p=p->next;
q=q->next;
}
}
printf("%d\n",n);
pri(head->next);
return 0;
}
2-5 E - 数据结构实验之链表三:链表的逆置
#include
#include
typedef struct Node
{
int data;
struct Node *next;
}node;
node *creat()//顺序建表
{
int x;//这个x要放在函数里,因为题中未说明输入的数
node *head,*p,*tail;
head=(node*)malloc(sizeof(node));
head-> next = NULL;
tail=head;
while(~scanf("%d",&x)&&x!=-1)
{
p=(node*)malloc(sizeof(node));
p->data=x;
p->next=NULL;
tail->next=p;
tail=p;
}
return head;
}
void pri(node *p)
{
while(p)
{
if(p->next==NULL)
printf("%d\n",p->data);
else
printf("%d ",p->data);
p=p->next;
}
}
void Inserve(node *head)//倒置
{
node *p,*q;
p=head->next;//p指向head所指向的
head->next=NULL;//head指向空
q=p->next;//q为p的下一位
while(p)
{
p->next=head->next;
head->next=p;//将p放到head的下一位
p=q;//下一次循环的p到上一次循环的q的位置,也就是说p向后一位
if(q)
q=q->next;//q向后一位
}
}
int main()
{
node *head;
head=creat();
Inserve(head);
pri(head->next);
return 0;
}
2-6 F - 数据结构实验之链表四:有序链表的归并
#include
#include
typedef struct Node
{
int data;
struct Node *next;
}node;
node *creat(int n)//顺序建链表
{
node *head,*p,*tail;
head=(node*)malloc(sizeof(node));
head-> next = NULL;
tail=head;
for(int i=0;idata);
p->next=NULL;
tail->next=p;
tail=p;
}
return head;
}
void pri(node *p)//输出函数
{
while(p)
{
if(p->next==NULL)
printf("%d\n",p->data);
else
printf("%d ",p->data);
p=p->next;
}
}
node *merge(node *head1,node *head2)//归并函数
{
node *p1,*p2,*tail,*head3;
p1=head1->next;//遍历链表head1
p2=head2->next;//遍历链表head2
head3=(node*)malloc(sizeof(node));//建立新的头节点head3;
head3->next=NULL;//让head3指向空
tail=head3;//tail也指向空
while(p1&&p2)
{
if(p1->data<=p2->data)//p1的值小于等于p2
{
tail->next=p1;//让tail指向p1
tail=p1;//让p1取代tail的位置
p1=p1->next;//p1向后走
}
else
{
tail->next=p2;
tail=p2;
p2=p2->next;
}//同上
}//实现从小到大归并排序
if(p1)
tail->next=p1;
else
tail->next=p2;//排序后,会出现有一条链表多出一个数的情况,此操作可以使多出来的数连接到新联表上;
return head3;
}
int main()
{
int n,m;
scanf("%d %d",&m,&n);
node *head1,*head2,*head3;
head1=creat(m);
head2=creat(n);
head3=merge(head1,head2);
pri(head3->next);
return 0;
}
2-7 G - 数据结构实验之链表五:单链表的拆分
#include
#include
typedef struct Node
{
int data;
struct Node *next;
}node;
int ji,ou;
node *creat(int n)//这里一定用逆序建链表,用顺序的话,后面可能会出现拆分不彻底情况(没错我之前出现了)
{
node *head,*p;
head=(node*)malloc(sizeof(node));
head-> next = NULL;
for(int i=0;idata);
p->next=head->next;
head->next=p;
}
return head;
}
void pri(node *p)
{
while(p)
{
if(p->next==NULL)
printf("%d\n",p->data);
else
printf("%d ",p->data);
p=p->next;
}
}
node *split(node *head1)
{
node *head2,*p,*q;
head2=(node*)malloc(sizeof(node));//建立一个新的头节点
head2->next=NULL;
p=head1->next;//遍历链表
q=p->next;
head1->next=NULL;//让head1指向空
while(p)
{
if(p->data%2==0)//若p值为偶数
{
ou++;//偶数个数+1
p->next=head1->next;
head1->next=p;//与链表逆置操作相同,逆序链表逆置,得到顺序链表
}
else
{
ji++;
p->next=head2->next;
head2->next=p;
}//奇数一样操纵
p=q;
if(q)
q=q->next;//逆置操作很常规
}
return head2;//返回head2,head2为奇数链表,此时head1也已经变为了偶数链表
}
int main()
{
int n;
scanf("%d",&n);
node *head1,*head2;
head1=creat(n);
head2=split(head1);
printf("%d %d\n",ou,ji);
pri(head1->next);
pri(head2->next);
return 0;
}
2-8 H - 数据结构实验之链表九:双向链表
#include
#include
#include //动态存储分配函数头文件
typedef struct Node
{
int data;
struct Node *next,*front;
}node;
node *creat(int n)
{
node *head,*p,*tail;
head=(node*)malloc(sizeof(node));
head->next = NULL;//head后指向空
head->front = NULL;//head前也指向空
tail=head;
for(int i=0; idata);
p->next=NULL;
tail->next=p;
p->front=tail;//让链表变为双向链表
tail=p;
}
return head;
}
int main()
{
int n,m;
scanf("%d %d",&n,&m);
node *head, *p;
head=creat(n);
while(m--)//m个关键字,相当于多组输入
{
p=head->next;//遍历链表
int x;
scanf("%d",&x);
while(p->data!=x)
p=p->next;//当p值不是x时,往后走
if(p->front==head)//如果找到位置的前驱是头节点
printf("%d\n",p->next->data);//输出后继的值
else if(p->next==NULL)//如果后继指向空
printf("%d\n",p->front->data);//输出前驱的值
else//中间情况
printf("%d %d\n",p->front->data,p->next->data);
}
return 0;
}
2-9 I - 约瑟夫问题
#include
#include
#include
typedef struct Node
{
int data;
struct Node *next;
} node;
node *creat(int n)
{
node *head,*p,*tail;
p=(node*)malloc(sizeof(node));
p->data=1;
p->next=NULL;
head=tail=p;//循环链表相当于没有真正意义上的头节点和尾节点,所以可以看作三个一样,但是“头节点”也需要赋值,也就是上面的p->data=1;
for(int i=2; i<=n; i++)
{
p=(node*)malloc(sizeof(node));
p->data=i;//给p赋值
p->next=NULL;
tail->next=p;
tail=p;
}//相当于是顺序建链表;
tail->next=head;//循环链表构建完成
return head;
}
int main()
{
int n,m;
scanf("%d %d",&n,&m);
node *head, *p,*q;
head=creat(n);
q=head;//也就是说q赋值为1;
while(q->next!=head)//q不回到那个head的q时
q=q->next;//q往下走
int a=0;//用于统计循环链表中向后走及位
while(q->next!=q)
{
p=q->next;
a++;//向后走的位数
if(a==m)//如果走到第m位了
{
q->next=p->next;//让p取代q
free(p);//释放p
a=0;//a回到0,重新开始记数
}
else
q=p;
}
printf("%d",q->data);//输出剩下的最后一个q
return 0;
}
2-10 J - 不敢死队问题
#include
#include
#include
typedef struct Node
{
int data;
struct Node *next;
} node;
node *creat(int n)//建立循环链表
{
node *head,*p,*tail;
p=(node*)malloc(sizeof(node));
p->data=1;
p->next=NULL;
head=tail=p;
for(int i=2; i<=n; i++)
{
p=(node*)malloc(sizeof(node));
p->data=i;
p->next=NULL;
tail->next=p;
tail=p;
}
tail->next=head;
return head;
}
int main()
{
int n;
while(~scanf("%d",&n)&&n!=0)
{
node *head, *p,*q;
head=creat(n);
q=head;
while(q->next!=head)
q=q->next;
int a=0,b=0;
while(q->next!=q)
{
p=q->next;
a++;
if(a==5)
{
if(p->data==1)
break;
q->next=p->next;
free(p);
a=0;
b++;
}
else
q=p;
}
printf("%d\n",b+1);
}
return 0;
}//与约瑟夫环差不多
加油加油加油!!!