数据结构单链表的基本运算

#include<stdlib.h>
#include<stdio.h>
#define ERROR 0
#define OK 1 
typedef char ElemType;
typedef struct Node //结点类型定义 
{
 	ElemType data;
 	struct Node * next;
}Node,*LinkList;  //*LinkList为结构指针类型 
LinkList Init() //初始化 
{
 	LinkList L;
 	L=(LinkList)malloc(sizeof(Node));  //建立头结点 
 	L->next=NULL;   //建立空的单链表L 
 	return L;
}
void CreateFromHead(LinkList L)//L是带头结点的空链表头指针,通过键盘输入表中元素值,利用头插法建立单链表L 
{
	Node *s;
	char c;
	int flag=1;
 while(flag)   //flag初值为1,当输入‘$’时,置flag为0,建表结束 
 {
  	c=getchar();
  	if(c!='$')
  	{
   		s=(Node *)malloc(sizeof(Node));   //建立新结点s 
   		s->data=c;
   		s->next=L->next;   //将s结点插入表头 
   		L->next=s;
  	}
  	else 
  	{
  		flag=0;  
  	}
 }
}
void NiZhi(LinkList L)
{
 	Node *p,*front,*back;
 	back=NULL;p=L->next;
 	while(p!=NULL)
 	{
  		front=p->next;
  		p->next=back;
  		back=p;
  		p=front;  
 	}
 	L->next=back;
}
void CreateFromTail(LinkList L)  //L是带有头结点的空链表头指针,通过键盘输入元素值,利用尾插法建立单链表L 
{
 	Node *r,*s;
 	int flag=1;   //设置一个标志,初值为1,当输入“$”时,flag为0,建表结束 
 	r=L;   //r指针动态指向链表的当前表尾,以便于做尾插入,其初值指向头结点
 	char c; 
 	while(flag) //循环输入表中元素值 ,将建立新结点s插入表尾 
 	{
  		c=getchar();
  		if(c!='$')
  		{
   			s=(Node * )malloc(sizeof(Node));
   			s->data=c;
   			r->next=s;
   			r=s;
  		}
  		else
  		{
   			flag=0;
   			r->next=NULL; //将最后一个结点的next域置为空,表示链表的结束 
  		}
 	}
} 
Node *Get(LinkList L,int i)
{
 	int j;
 	Node *p;
 	if(i<=0)
 	{
	 		return NULL;
	}
 	p=L;
	j=0; //从头结点开始扫描 
 	if(i>ListLength(p))
 	{
  		printf("查找位置不合理!\n");
  		return NULL;
 	} //找不到,查找位置超出表长 
 	while(p->next!=NULL&&j<i)
 	{
  		p=p->next;//扫描下一结点 
  		j++;  //已扫描结点计数器 
 	}
 	if(i=j)
 	{
  		return p;  //找到了第i个结点 
 	}
}
int Locate(LinkList L,ElemType key)
{
 	int j=1;
 	Node *p;
 	p=L->next;   //从表中第一个结点开始 
 	while(p!=NULL) 
 	{  //当前表未查完 
 		 if(key==p->data)
   		{
    			printf("查找字符%c是L1中第%d个元素\n",key,j);
    			p=p->next;
    			j++;
   		}
  		else 
  		{
   			p=p->next;
  			j++;
  		}
 	}//找到结点值=key时退出循环 ;
	return 0; 
}
int ListLength(LinkList L)
{
 	Node *p;
 	p=L->next;
 	int j=0;   //用来存放单链表的长度 
 	while(p!=NULL)
 	{
  		p=p->next;
  		j++;
 	} 
 	return j;  //j为求得的单链表的长度 
}

int InsList(LinkList L,int i,ElemType e)
{
 	Node *pre,*s;
 	int k;
 	if(i<=0)
 	{
  		return ERROR;
 	} 
  	pre=L;
  	k=0;//从头开始查找第i-1个结点 
  	while(pre!=NULL&&k<i-1)  //表未查完且未查到第i-1个时重复,找到pre指向第i-1个 
  	{
   		pre=pre->next;
   		k=k+1;
  	} 
  	if(pre==NULL)  //如当前位置pre为空表示已找完,但还未数到第i个,说明插入位置不合理 
  	{
   		printf("插入位置不合理!");
   		return ERROR;
  	}
  	s=(Node *)malloc(sizeof(Node));  //申请一个新结点s 
  	s->data=e;  //值e插入s的数据域 
  	s->next=pre->next;//修改指针,完成插入操作 
  	pre->next=s;
  	return OK;
}

ElemType DelList(LinkList L,int i) //删除结点
{
 	ElemType e; 
 	Node *pre,*r;
 	int k;
 	pre=L;k=0;
 	while(pre->next!=NULL&&k<i) //寻找被删除的结点i的前驱结点i-1使p指向它 
 	{
  		pre=pre->next;
  		k=k+1;
 	}
 	if(pre->next==NULL)
 	{
  		printf("删除结点的位置i不合理!");
  		return ERROR;
 	}  //查找第i-1个结点 
 	r=pre->next;
 	pre->next=r->next;  //修改指针,删除结点r 
 	e=r->data;
 	free(r);  //释放被删除结点所占的内存空间 
 	return e;
}

LinkList MergeLinkList(LinkList LA,LinkList LB)  //将递增有序的单链表LA和LB合成一个递增有序的单链表LC 
{
 	Node *pa,*pb;
 	LinkList LC=Init(); 
 	//将LC初置空表 。pa和pb分别指向两个单链表LA和LB中的第一个结点,r 初置为LC且r始终指向LC的表尾 
 	pa=LA->next;
 	pb=LB->next;
 	LC=LA;
 	LC->next=NULL;
 	Node *r=LC;//当两个表中均未处理完时,比较选择将较小值结点插入到新表LC中 
 	while(pa!=NULL&&pb!=NULL)
 	{
  		if(pa->data<=pb->data)
  		{
   			r->next=pa;r=pa;pa=pa->next;
  		}
  		else
  		{
   			r->next=pb;r=pb;pb=pb->next;
  		}
 	}
 	if(pa)  //若表LA未完,将表LA中后续元素链到新表LC表尾 
 	{
  		r->next=pa;
 	}
 	else
 	{
  		r->next=pb;
 	}
 	free(LB);
 	return (LC);
}

void Print(LinkList L)//输出函数
{
 	Node *p=L->next;
 	while(p)
 	{
  		printf("%c",p->data);
  		p=p->next;
 	}
}

int Empty(LinkList L) //判断是否为空
{
 	if(L->next==NULL)
 	{
  		return 1;
 	}
 	else 
 	{
  		return 0;
 	}
} 

int main()
{
 	int a;
 	int b;
 	int c;
 	int d;
 	int e;
 	Node * w;
 	printf("请输入两个表L1和L2,以“$”结束:\n");
 	LinkList L1;
 	LinkList L2;
 
 	L1=Init();
 	L2=Init();
 
 	CreateFromHead(L1);
 	printf("\n头插法建表L1:\n");
 	Print(L1);
 	NiZhi(L1);
 	printf("\n逆置后为L1:\n");
 	Print(L1);
 	printf("\n\n");
 
 	CreateFromTail(L2);
 	printf("尾插法建表L2:");
 	Print(L2);
 
 	ListLength(L1);
 	printf("\n\nL1的表长为:%d\n",ListLength(L1));
 
 
 	printf("L1中查找序号为:\n");
 	scanf("%d",&a);
 	w=Get(L1,a);
 	printf("L1中第%d个元素的值是%c\n",a,w->data);
 
 	printf("\nL1中要查找的字符为:"); 
 	scanf("%*c%c",&b);
 	Locate(L1,b);
 	 
 	printf("\nL1中插入的位置为:");
 	scanf("%d",&c);
 	printf("插入的字符为:");
 	scanf("%*c%c",&d);
 	InsList(L1,c,d);
 	printf("在L1中第%d个位置插入值为%c的新结点后为:\n",c,d);
 	Print(L1);
 
 	printf("\n\n删除L2的位置为:");
 	scanf("%d",&e);
 	DelList(L2,e);
 	printf("删除后的L2为:");
 	Print(L2);
 
 	if(Empty(L1))
 	{
  		printf("\n\n表L1为空!\n");
 	}
 	else
 	{
  		printf("\n表L1非空!");
 	} 
 
 	printf("\n\nL1和L2合并后为:");
 	Print(MergeLinkList(L1,L2));
 	return 0;
}

运行结果如下:
在这里插入图片描述

发布了30 篇原创文章 · 获赞 32 · 访问量 974

猜你喜欢

转载自blog.csdn.net/cleverlemon/article/details/102623225