需求:掌握链表的简单操作(增删查改)详解在备注中指出
#include <iostream>
#include <stdlib.h>
#include <stdio.h>
/* run this program using the console pauser or add your own getch, system("pause") or input loop */
struct node{
int data;//数据
node* next;//指针
};
node* creat(int array[],int n)// 创建一个长度为n的循环列表
{
node *p,*head,*pre;// 创建现在指针,头指针,前指针
head =new node;// 新创建一个空的头地址
head->next=NULL;// 先进行置空
pre=head;// 将前指针置为头结点
for(int i=0;i<n;i++)// 创建n个长度的链表
{
p=new node; // 创建新节点
p->next=NULL;// 先进行置空
pre->next=p;// 和新建的连接
p->data=array[i];// 将新建节点赋值
pre=p;// 推进
}
p->next=head;// 因为是循环列表将尾指针指向头指针
return head;// 返回头指针(头指针data没赋值)
}
void delet(node* head,int length,int m)// 将指定head头的链表的第m个删除并输出(循环 )
{
node *pre,*p;
int count=1,sum=0;//创建计数器(p的位置)和sum
pre=head;//头结点指定head
p=head->next;//p(现在节点)指向第1个元素
while(length!=0)//当链表中没元素时退出
{
if(p==head)//当循环到头结点时因为不应该进行计数所以推进
{
pre=pre->next;//将两个节点推进
p=p->next;
}
if(count==m)//如果当p(现在节点)的计数等于m ,删除该p节点
{
printf("第%d个出队:%d号学生\n",++sum,p->data);//输出 该删除的节点
pre->next=p->next;//直接将p前一节点的指针域赋为p的下一个节点的地址(跳过p节点)
delete(p);//释放空间 此时p的地址为空
p=pre->next;// 将p的地址赋为pre的下一个地址(始终保持p在pre前)
length--;//长度减一
count=0;//重置计数器
}
else//如果没有删除节点那么p节点就没有变化,此时我们推进
{
pre=pre->next;
p=p->next;
}
count++;//推进一次计数器加一,当删除一个元素后,p直接为下一个地址,等于说p推进了一次,那么计数器也应该加一
}
}
int main() {
int n,m;
int arr[1000];
for(int i=0;i<n;i++)//将学生编号
{
arr[i]=i+1;//学生编号为1,2,3,4....
}
printf("请输入学生数目n 循环次数m\n1代表1号学生\n");
scanf("%d%d",&n,&m);//录入n,m
node* l=creat(arr,n);//调用两个方法
delet(l,n,m);
return 0;
}