1. 程式人生 > >【資料結構】單鏈表的應用(C語言)

【資料結構】單鏈表的應用(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;
}