【数据结构】单链表的应用(C语言)

1、设计一个算法,求一个单链表中的节点数

2、设计一个算法,在一个单链表中值为y的结点前插入一个值为x的结点(值为x的新结点为成为值为y的结点前驱结点)

3、设计一个算法,判断单链表中各结点是否有序

4、设计一个算法,利用单链表中原来的结点空间逆转一个单链表

5、设计一个算法,将一个值为自然数的单链表拆分为两个单链表,原表中保留值为偶数的结点,而值为基数的结点按他们在原表中的相对次序组成一个新的单链表。

6、设计一个算法,对一个有序的单链表删除所有值大于x而不大于y的结点

 

下面是头文件(包括各种链表的算法,不足之处还望指正)

#ifndef HEAD_LINK_H_INCLUDED
#define HEAD_LINK_H_INCLUDED

#include <stdio.h>
#include <stdlib.h>
typedef int datatype;
typedef struct link_node
{
	datatype info;
	struct link_node *next;
}N;


//创建一个空链表
N *init()
{
	return NULL;
}

//创建一个单链表(已知长度)
N *creat_length(int len,N *head)
{
	int a,i;
	N *p,*h=head,*q;
	if (len<1)
	{
		return NULL;
	}
	else
	{
		for(i=1;i<=len;i++)
		{
			scanf("%d",&a);
			p=(N*)malloc(sizeof(N));
			p->info=a;
			if(i==1)
			{
				p->next=NULL;
				h=p;
				q=p;
			}
			else
			{
				q->next=p;
				q=p;
				p->next=NULL;
			}
		}
		return h;
	}
}

//创建一个单链表(未知长度)
N* creat(N *head)
{
	printf("创建一个单链表,以输入-1作为结束!!!\n");
	N *p,*q,*h=head;
	int x;
	scanf("%d",&x);
	while(x!=-1)
	{
		p=(N*)malloc(sizeof(N));
		p->info=x;
		p->next=NULL; 
		if(!h)
		{
			h=p;
			q=p;
		}
		else
		{
			q->next=p;
			q=p;
		}
		scanf("%d",&x);
	} 
	return h;
} 

//输出单链表中各节点的值
void display (N *head)
{
	N *p=head;
	if(!p)
	{
		printf("\n该链表是空的!\n");
	}
	else
	{
		while(p)
		{
			printf("%d",p->info);
			if(p->next)
			{
				printf(" -> ");
			}
			p=p->next;
		}
		printf("\n");
	}
}

//在单链表中查找第i个节点的值
N *find(N *head ,int i)
{
	int j=1;
	N *p=head;
	if(i<1)
	{
		return NULL;
	}
	while(p && i!=j)
	{
		p=p->next;j++;
	}
	return p;
}

//在单链表中找出值为i的位置
int node_position(N* head,int i)
{
	N *p;
	int j=1;
	p=head;
	while(p && p->info!=i)
	{
		p=p->next;
		j++;
	}
	if(!p)
	{
		return 0;
	}
	else
	{
		return j;
	}
} 


//计算单链表的节点数目
int counts(N *head)
{
	N *p;
	int count=0;
	p=head;
	while(p)
	{
		count++;
		p=p->next;
	}
	return count;
}

//在单链表第i个结点后插入一个值为x的新新结点
N *insert(N *head,datatype x,int i)
{
	N *p,*q;
	q=find(head,i);/*找到第i个结点*/
	if(!q && i!=0)
	{
		printf("找不到第%d个节点,不能插入%d",i,x);
	}
	else
	{
		p=(N*)malloc(sizeof(N));
		p->info=x;
		if(i==0)
		{
			p->next=head;
			head=p;
		}
		else
		{
			p->next=q->next;
			q->next=p;
		}
	}
	return head;
}

//从单链表中删除一个值为x的节点
N *dele_num(N *head,datatype x)
{
	N *pre,*p;
	if(!head)
	{
		printf("该单链表是空的!");
		return head;
	}
	p=head;
	while(p && p->info!=x)/*没有找到并且没有找完*/
	{
		pre=p;
		p=p->next;/*pre指向p的前驱结点*/
	}
	if(p)
	{
		if(!pre)/*要删除第一个结点*/
		{
		 	head=head->next;
		}
		else
		{
			pre->next=p->next;
			free(p);
		}
	}
	return head;
}

//删除第i个结点
N *dele_node(N *head,int i)
{
	N *q,*p;
	if(!head)
	{
		printf("该单链表是空的!");
		return head;
	}
	if(i==1)
	{
		head=head->next;
	}
	else
	{
		q=find(head,i-1);
		p=find(head,i);
		q->next=p->next;		
	}
	return head;	 
}
 
//将单链表进行逆转
N *inverse(N* head)
{
	N *p=head->next,*q,*h=head;
	h->next=NULL;
	while(p)
	{
		q=p;
		p=p->next;
		q->next=h;
		h=q;
	}
	return h;
} 

//菜单 
void menu()
{
	printf("相关操作:【1、创建空链表 2、链表初始化(已知长度) 3、计算结点数 4、第i个结点的结点值 5、值为x的结点的位置 6、插入操作 7、删除值为x的结点 8、删除某个结点】");
}

//判断是否有序
int  judge (N *head) 
{ 
	N *p= head->next; 
	int tem; 
	int i = 0, j = 0, k = 0, l = 0; 
	while (p->next != NULL)
 	{ 
		tem = p->info; 
		p = p->next; 
		if (tem > p->info) 
			i ++; 
		else if (tem == p->info) 
			k ++; 
		else 
			l ++; 
		j ++; 
	} 
	if (i+k == j || l+k == j ) 
		return 1; 
	else return 0; 
}   
#endif // HEAD_LINK_H_INCLUDED

下面是上面六题的程序

#include "stdio.h"
#include "head_link.h"
#define MAXSIZE 100
int main()
{
	int x,y,position,a[MAXSIZE],temp;
	N *h,*p,*q,*h1,*p1,*q1;
	h=init();
	printf("查找结点数:\n"); 
	h=creat(h);
	display(h);
	printf("一共有%d个结点\n\n",counts(h));
/*****************************/
/*在值为y的结点前插入一个值为x的结点*/ 
	printf("在值为y的结点前插入一个值为x的结点:");
	printf("插入:"); 
	scanf("%d",&x);
	printf("查找:");
	scanf("%d",&y);
	position=node_position(h,y);
	h=insert(h,x,position-1);
	display(h);
/*****************************/
/*奇数偶数分离*/ 
	p=h;
	h1=init();
	//p1是奇数节点
	while(p)
	{
		if((p->info)%2!=0)
		{
			p1=(N*)malloc(sizeof(N));
			p1->info=p->info;
			p1->next=NULL;
			if(!h1)
			{
				q1=p1;
				h1=p1;
				//删除原始数列的第一个结点 
				h=dele_node(h,node_position(h,p->info));
			}
			else
			{
				q1->next=p1;
				q1=p1;	
				h=dele_node(h,node_position(h,p->info));	
			}
		}
		p=p->next;
	}
	printf("偶数列:\n"); 
	display(h);
	printf("奇数列:\n"); 
	display(h1);
/*****************************/
/*逆置*/
	h=init();
	h=creat(h);
	h=inverse(h);
	printf("逆置以后:\n"); 
	display(h);
/*****************************/
/*对特定的数进行删除*/	
	h=init();
	h=creat(h);
	display(h);
	printf("输入边界:\n");
	scanf_s("%d%d",&x,&y);
	p=h;
	while(p)
	{
		if(p->info>x && p->info<=y)
		{
			h=dele_node(h,node_position(h,p->info));
		}
		p=p->next;
	}
	display(h);
/*****************************/
/*判断是否有序*/
	printf("判断有序\n"); 
	h=init();
	h=creat(h);
	if(judge (h) )
	{
		printf("有序\n"); 
	}
	else
	{
		printf("无序\n"); 
	}
	return 0;
}
	

 

  • 5
    点赞
  • 39
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值