1. 程式人生 > >單鏈表應用舉例(單鏈表A和單鏈表B的元素都是非遞減排列,利用單鏈表的基本運算,將它們合併成一個單鏈表C,要求C也是非遞減序列)

單鏈表應用舉例(單鏈表A和單鏈表B的元素都是非遞減排列,利用單鏈表的基本運算,將它們合併成一個單鏈表C,要求C也是非遞減序列)

標頭檔案:函式的定義

#include <stdio.h>
#include <malloc.h>
#include <stdlib.h>
#include <string.h>
typedef int ElemType;
typedef struct Node
{
	ElemType data;
	struct Node *next;
}ListNode,*LinkList;//ListNode連結串列的結點型別,LinkList指向連結串列結點的指標型別

void InitList(LinkList *head);//單鏈表的初始化操作
int ListEmpty(LinkList head);//判斷單鏈表是否為空
ListNode* Get(LinkList head,int i);//按序號查詢操作
ListNode* LocateElem(LinkList head,ElemType e);//按內容查詢操作
int LocatePos(LinkList head,ElemType e);//定位操作
int InsertList(LinkList head,int i,ElemType e);//插入操作
int DeleteList(LinkList head,int i,ElemType *e);//刪除操作
int ListLength(LinkList head);//求表長操作
void DestroyList(LinkList head);//銷燬連結串列操作


函式的宣告

#include "連結串列.h"

void InitList(LinkList *head)//單鏈表的初始化操作
{
	if((*head =(LinkList)malloc(sizeof(ListNode))) == NULL)
	{
		exit(-1);
	}
	(*head)->next = NULL;
}

int ListEmpty(LinkList head)//判斷單鏈表是否為空
{
	if(head->next == NULL)
	{
		return 1;
	}
	else
	{
		return 0;
	}
}

ListNode* Get(LinkList head,int i)//按序號查詢操作
{
	ListNode *p;
	int j = 0;
	p = head;
	if(ListEmpty(head))//在查詢第i個元素之前,判斷連結串列是否為空
	{
		return NULL;
	}
	if (i < 1)//在查詢第i個元素之前,判斷連結串列是否合法
	{
		return NULL;
	}
	while(p->next != NULL && j < i)
	{
		p = p->next ;
		j++;
	}
	if(j == i)
	{
		return p;//找到第i個結點,返回指標p
	}
	else
	{
		return NULL;//如果沒有找到第i個結點,返回NULL
	}
}

ListNode* LocateElem(LinkList head,ElemType e)//按內容查詢操作
{
	ListNode *p;
	p = head->next ;//指標p指向第一個節、結點
	while(p)
	{
		if(p->data != e)//找到與e相等的元素,返回該序號
		{
			p = p->next ;
		}
		else
		{
			break;
		}
	}
	return p;
}

int LocatePos(LinkList head,ElemType e)//定位操作
{
	ListNode *p;
	int i = 1;
	if(ListEmpty(head))//在查詢第i個元素之前,判斷連結串列是否為空
	{
		return NULL;
	}
	p = head->next ;
	while(p)
	{
		if(p->data == e)
		{
			return i;
		}
		else
		{
			p = p->next ;
			i++;
		}
	}
	if(!p)
	{
		return 0;
	}
}

int InsertList(LinkList head,int i,ElemType e)//插入操作
{
	ListNode *p,*pre;//定義指向第i個元素的前驅指標pre,指標p指向新生成的結點
	int j = 0;
	pre = head;//指標p指向頭結點
	while(pre->next != NULL && j < i-1)//找到i-1個結點,即第i個結點的前驅結點
	{
		pre = pre->next ;
		j++;
	}
	if(j != i-1)//如果沒找到則插入位置錯誤
	{
		printf("插入位置錯誤");
		return 0;
	}
	if((p = (ListNode*)malloc(sizeof(ListNode))) == NULL)//新生成一個結點,並將e賦值給該結點的資料域
	{
		exit(-1);
	}
	p->data = e;
	p->next = pre->next;//插入結點操作
	pre->next = p;
	return 1;
}

int DeleteList(LinkList head,int i,ElemType *e)//刪除操作
{
	ListNode *pre,*p;
	pre = head;
	int j = 0;
	while(pre->next != NULL && pre->next->next != NULL && j < i-1)//判斷是否找到前驅結點
	{
		pre = pre->next ;
		j++;
	}
	if(j != i-1)//如果沒有找到要刪除的位置,說明刪除結點位置錯誤
	{
		printf("刪除位置錯誤");
		return 0;
	}
	p = pre->next;//指標p指向單鏈表中的第i個結點,並將該結點的資料域值賦值給e
	*e = p->data;
	pre->next = p->next;//將前驅結點的指標域指向要刪除結點的下一個結點,也就是將p指向的結點與單鏈表斷開
	free(p);//釋放p指向的節點
	return 1;
}

int ListLength(LinkList head)//求表長操作
{
	ListNode *p;
	int count = 0;
	p = head;
	while(p->next != NULL)
	{
		p = p->next ;
		count++;
	}
	return count;
}

void DestroyList(LinkList head)//銷燬連結串列操作
{
	ListNode *p,*q;
	p = head;
	while(p != NULL)
	{
		q = p;
		p = p->next ;
		free(q);
	}
}


函式的應用

#include "連結串列.h"
//單鏈表A和單鏈表B的元素都是非遞減排列,利用單鏈表的基本運算,將它們合併成一個單鏈表C,要求C也是非遞減序列。
void MergeList(LinkList A,LinkList B,LinkList *C)
{
	ListNode *pa,*pb,*pc;
	pa = A->next ;
	pb = B->next ;
	*C = A;
	(*C)->next = NULL;
	pc = *C;
	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(B);
}
int main(void)
{
	int i;
	ElemType a[] = {6,7,9,14,37,45,65,67};
	ElemType b[] = {3,7,11,34,45,89};
	LinkList A,B,C;
	ListNode *p;
	InitList(&A);
	InitList(&B);
	for(i = 1;i <= sizeof(a)/sizeof(a[0]);i++)
	{
		if(0 == InsertList(A,i,a[i-1]))
		{
			printf("位置不合法!");
			return 0;
		}
	}
	for(i = 1;i <= sizeof(b)/sizeof(b[0]);i++)
	{
		if(0 == InsertList(B,i,b[i-1]))
		{
			printf("位置不合法!");
			return 0;
		}
	}
	printf("單鏈表A中的元素有%d個\n",ListLength(A));
	for(i = 1;i <= ListLength(A);i++)
	{
		p = Get(A,i);
		if(p)
		{
			printf("%4d",p->data);
		}
	}
	printf("\n");
	printf("單鏈表B中的元素有%d個\n",ListLength(B));
	for(i = 1;i <= ListLength(B);i++)
	{
		p = Get(B,i);
		if(p)
		{
			printf("%4d",p->data);
		}
	}
	printf("\n");
	MergeList(A,B,&C);
	printf("將單鏈表A和單鏈表B中的元素合併到單鏈表C中的元素有%d個\n",ListLength(C));
	for(i = 1;i <= ListLength(C);i++)
	{
		p = Get(C,i);
		if(p)
		{
			printf("%4d",p->data);
		}
	}
	printf("\n");
	return 0;
}