#include "stdio.h"
#include "malloc.h"
#define OK 1
#define ERROR 0
#define INFEASIBLE -1
#define OVERFLOW -2
#define TRUE 1
#define FALSE 0
#define List_Init_Size 10
#define ListIncrement 2
typedef int ET;
typedef ET * Ep;
typedef int Status;
typedef struct LNode{
ET data;
struct LNode *next;
}LNode, *LinkList;
LinkList La,Lb,Lc;
//打印链表中的元素
void printlk(LinkList L) {
LinkList p;
p=L->next;
while (p) {
printf("%d ",p->data);
p = p->next;
}
printf("\n");
}
//生成一个空链表
LinkList initList()
{
LinkList L;
L=(LinkList)malloc(sizeof(LNode));
L->next=NULL;
return L;
}
//头插法生成链表
void CreatList(LinkList L )
{
int j,n,k;
LinkList p;
printf("请输入链表中的元素个数 : ");
scanf("%d",&n);
L->next=NULL;
for (j=n;j>0;j--)
{
p=(LinkList)malloc(sizeof(LNode));//生成一个结点
printf("请读入第%d个元素值\n",j);
scanf ("%d", &k);
p->data = k;
p->next = L->next;
L->next = p;
}
}
int CreatList1(LinkList L)
{ //尾插法生成链表
LNode *p,*r;
int i,n;
printf("请输入链表中的元素个数 :");
scanf("%d",&n);
r=L;
for(i=1;i<=n;i++){
p=(LinkList)malloc(sizeof(LNode));
printf("请输入值:\n");
scanf("%d",&p->data);
r->next=p;
r=p;
}
r->next=NULL;//处理尾结点
return 1;
}
void MenuList()
{
printf("\n\n\n**************************\n");
printf(" 1 ------- 初始化 LA\n");
printf(" 2 ------- 生成链表La\n");
printf(" 3 ------- 向链表中第i号位置插入元素\n");
printf(" 4 ------- 删除链表中第i号元素 \n");
printf(" 5 ------- 求链表中元素个数 \n");
printf(" 6 ------- 查找链表中值为x的第一个元素 \n");
printf(" 7 ------- 查找链表中第i号元素 \n");
printf(" 8 ------- 链表的归并 \n");
printf(" 9 ------- 单链表La的倒置 \n");
printf(" 10 ------- 删除单链表La中值为X的结点\n");
printf(" 11 ------- 约瑟夫环问题求解 \n");
printf(" 12 ------- 输出LA中的元素 \n");
printf("**************************\n");
}
int Insert(LinkList L,int i,int x)
{ //在第i个位置插入元素x
LinkList p,q;
int j=0;
if(i<1)
return 0;
p=L;//让指针p指向头结点
while(p&&j<i-1) {
p=p->next ;
j++;//使指针p指向第i个元素的前驱
}
if(p==NULL)
return 1;//链表为空
q=(LinkList)malloc(sizeof(LNode));
q->data=x;
q->next=p->next;
p->next=q;
return 2;
}
int deletedata(LinkList L,int i)
{//删除第i个元素
LinkList p,q;
int j=0;
p=L;
while(p->next&&j<i-1)//先将指针p定位到第i个元素的前驱
{
p=p->next;
j++;
}
if(p->next==NULL)
return 0;//链表为空
q=p->next;//q指向被删结点
p->next=q->next;
free(q);
return 1;
}
int locatedata(LinkList L,int i)
{//查找第i个元素
LinkList p;
ET e;
int j=0;
p=L;
while(p->next&&j<i)
{
p=p->next;
j++;
}
e=p->data;
return e;
}
LinkList finddata(LinkList L,int x)
{ //查找值为X的元素
LinkList p,q;
p=L->next;//p指向首元结点
q=L;
while(p&&p->data!=x) {
p=p->next;
q=q->next;
}
if(p==NULL)
printf("该链表中不存在值为%d的元素",x);
return q;//返回值为x的结点的前驱
}
int sqlength(LinkList L)
{//求链表中的元素个数
LinkList p;
int count=0;
p=L->next;
while(p) {
p=p->next;
count++;
}
return count;
}
int Un(LinkList L)
{//将链表倒置
LinkList p,r;
p=L->next;//p指向首元结点
if(p==NULL)
return 0;
L->next=NULL;//先将头结点断开
while(p) {//采用头插法倒置链表
r=p->next;
p->next=L->next;
L->next=p;
p=r;
}
return 1;
}
int delx(LinkList L,int x)
{//删除所有值为x的结点
LinkList p,q,t;//q指向p的前驱
p=L->next;
q=L;
if(p==NULL)
return 0;//表为空
while(p!=NULL){
if(p->data==x){
t=p;//t指向被删结点
p=p->next;
q->next=p;
free(t);
}
else{
q=p;
p=p->next;
}
}
return 1;
}
LinkList meg_sql(LinkList La, LinkList Lb, LinkList Lc)
{//合并递减的La和递减的Lb
Lb=initList();
printf("--创建递减的链表Lb--\n");
CreatList1(Lb);
Lc=initList();
LinkList pa,pb,pc;
pa=La->next;
pb=Lb->next;
pc=Lc;
while(pa&&pb){
if(pa->data>=pb->data){
pc->next=pa;
pc=pa;
pa=pa->next;
}
else{
pc->next=pb;
pc=pb;
pb=pb->next;
}
}
pc->next=pa?pa:pb;
free(Lb);
return Lc;
}
void simplify_list(LinkList head,int n){//删除绝对值相等的结点
//可申请n+1个位置的辅助数组
LinkList temp;
int* q = (int *)malloc(sizeof(int)*(n+1));
for(int i=0;i<n;i++){//数组元素初值设为0
q[i] = 0;
}
LNode *p = head->next;//指向首元结点
LinkList pre = head;
while(p !=NULL){
int data = p->data;
int addr = data >0? data:-data;
if(q[addr] ==1){//需要删除当前结点p
temp = p;//删除操作
pre->next = p->next;
p=p->next;
free(temp);}
else{//保留当前节点;
q[addr]=1;
pre = p;
p = p->next;}
}
free(q); //释放辅助空间;
}
LinkList initLink(int n){//循环链表初始化
LinkList head=(LinkList)malloc(sizeof(LNode));
head->data=1;
head->next=NULL;
LinkList p=head;
for (int i=2; i<=n; i++) {
LinkList q=(LinkList)malloc(sizeof(LNode));
q->data=i;
q->next=NULL;
p->next=q;
p=p->next;
}
p->next=head;//首尾相连
return head;
}
void joseph(LinkList head,int k,int m){
LinkList r=head;
LinkList p=head;
//找到编号为m的位置
while (p->data!=m) {
r=p;
p=p->next;
}
//从编号为m的位置开始,只有符合p->next==p时,说明链表中除了p结点,所有编号都出列了,
while (p->next!=p) {
//找到从m开始报数,报k的位置,并且还要知道k-1的位置r,方便做删除操作。
for (int i=1; i<k; i++) {
r=p;
p=p->next;
}
r->next=p->next;//从链表上将p结点摘下来
printf("出列位置为:%d\n",p->data);
free(p);
p=r->next;//继续使用p指针指向出列编号的下一个编号
}
printf("出列位置为:%d\n",p->data);//最后一个出列
free(p);
}
int main()
{ int i=100,s,I,x;
LinkList p;
while(i!=0)
{
MenuList() ;
printf("请输入选择:");
scanf("%d" ,&i);
if (i==1){
La=initList();
printf("初始化成功!\n");
}
if (i==2){
CreatList1(La);
printf("创建成功!\n");
}
if (i==3){
printf("请输入要插入的元素的位置:");
scanf("%d",&I);
printf("请输入要插入的元素的值:");
scanf("%d",&x);
s=Insert(La,I,x);
if(s==0)
printf("插入位置不合法!\n");
else if(s==1)
printf("该链表为空!\n");
else
printf("插入成功!\n");
}
if (i==4){
printf("请输入要删除的元素的位置:");
scanf("%d",&I);
s=deletedata(La,I);
if(s==0)
printf("该链表为空!\n") ;
printf("删除成功!\n");
}
if(i==5){
s=sqlength(La);
printf("该链表中元素个数为:%d",s);
}
if(i==6){
printf("请输入要查找的元素的值:");
scanf("%d",&I);
p=finddata(La,I);
int n;
LinkList q;
q=La;
for(n=1;p!=q;n++){
q=q->next;
}
printf("值为%d的元素第一次出现在链表的第%d个\n",I,n);
printf("其地址为:%p",p);
}
if (i==7){
printf("请输入要查找的元素的位置:");
scanf("%d",&I) ;
s=locatedata(La,I);
printf("第%d个元素的值为:%d",I,s);
}
if(i==8){
Lc=meg_sql(La,Lb,Lc);
printf("合并后的链表为:\n");
printlk(Lc);
}
if(i==9){
s=Un(La);
if(s==0)
printf("该链表为空\n");
printf("倒置后的链表为:\n");
printlk(La);
}
if(i==10){
printf("请输入要删除的结点的值:");
scanf("%d",&I) ;
s=delx(La,I) ;
if(s==0)
printf("不存在值等于%d结点",I);
printf("删除成功!\n");
}
if(i==11){
printf("请输入循环链表中的元素个数:");
int n;
scanf("%d",&n);
LinkList head=initLink(n);
int m;
printf("开始报数的位置为(k>1且k<%d):",n);
scanf("%d",&m);
int k;
printf("隔多少个位置出列:");
scanf("%d",&k);
joseph(head, k, m);
}
if(i==12){
printlk(La);
}
if(i==13){
La=initList();
printf("清空La成功!");
}
if(i==14){
printf("请输入该链表中的元素个数:");
scanf("%d",&I);
simplify_list(La,I);
printf("删除成功!");
}
}
}
代码-链表
于 2022-08-15 18:31:01 首次发布
该程序用C语言实现了链表的初始化、元素插入、删除、查找、合并、倒置、删除指定值节点等功能。此外,还提供了约瑟夫环问题的解决方案,用户可以选择不同操作进行交互式操作。程序通过头插法和尾插法生成链表,并提供了链表元素的打印功能。
摘要由CSDN通过智能技术生成