1. 程式人生 > >資料結構-單鏈表

資料結構-單鏈表

說明

    與順序表相比,允許儲存空間不連續,插入刪除時不需要移動大量的元素,只需修改指標即可,但查詢某個元素,只能從頭遍歷整個連結串列。

程式碼

/*
**	slink create by yubo.wang 2018.9.12
*/
#include <stdio.h>
#include <stdlib.h>

typedef char ElemType;

typedef struct node
{
	ElemType data;
	struct node *next;
}SLink;

SLink *MaxNode(SLink *L);

void InitList(SLink *&L) /*SLink *&L作為引用型引數或者用二級指標SLink **L*/
{
	L=(SLink *)malloc(sizeof(SLink));
	L->next = NULL;
}

int GetLength(SLink *L)
{
	int i=0;
	SLink *p=L->next;
	while(p != NULL)
	{
		i++;
		p=p->next;
	}
	return i;
}

int GetElem(SLink *L,int i,ElemType &e)
{
	int j=1;
	SLink *p=L->next;
	if(i<1 || i>GetLength(L))
		return 0;
	while(j<i)
	{
		p=p->next;
		j++;
	}
	e=p->data;
	return 1;
}

int Locate(SLink *L,ElemType x)
{
	int i=1;
	SLink *p=L->next;
	while(p!=NULL && p->data!=x)
	{
		p=p->next;
		i++;		
	}
	if(NULL == p)
		return 0;
	else
		return i;
}

int InsElem(SLink *L,ElemType x,int i)//初始化是尾插,也可中途插入
{
	int j=1;
	SLink *p=L,*s;
	s=(SLink *)malloc(sizeof(SLink));
	s->data=x;
	s->next=NULL;
	if(i<1 || i>GetLength(L)+1)//防止i越界
		return 0;

	while(j<i)
	{
		p=p->next;
		j++;
	}
	s->next = p->next;
	p->next = s;
	return 1;
}

int DelElem(SLink *L,int i)
{
	int j=1;
	SLink *p=L,*q;
	if(i<1 || i>GetLength(L))
		return 0;
	while(j<i)
	{
		p=p->next;
		j++;
	}
	q=p->next;
	printf("%c\n", q->data);
	p->next=q->next;
	free(q);
	return 1;
}

void DispList(SLink *L)
{
	SLink *p=L->next;
	while(p != NULL)
	{
		printf("%c ", p->data);
		p=p->next;
	}
	printf("\n");
}

int main()
{
	int i;
	ElemType e;
	SLink *L=NULL;
	InitList(L);//initial head

	InsElem(L,'a',1);
	InsElem(L,'b',2);
	InsElem(L,'c',3);
	InsElem(L,'d',4);
	InsElem(L,'e',5);
	InsElem(L,'f',6);

	printf("List:");
	DispList(L);

	printf("Length: %d\n", GetLength(L));

	i=3;
	GetElem(L,i,e);
	printf("index %d data is:%c\n", i,e);

	e='e';
	printf("data %c index is: %d\n", e,Locate(L,e));

	i=4;
	printf("delete index %d data ", i);
	DelElem(L,i);

	i=2;
	e='w';
	printf("insert index %d data %c\n", i, e);
	InsElem(L,e,2);

	printf("List:");
	DispList(L);

	printf("MaxNode:%c\n", MaxNode(L)->data);
}

/*通過一趟遍歷返回單鏈表元素最大值的結點*/
SLink *MaxNode(SLink *L)
{
	SLink *p=L->next,*q=p;//p用來遍歷,q用來記錄最大的值結點
	while(p != NULL)
	{
		if(p->data > q->data)
			q=p;
		p=p->next;
	}
	return q;
}

/*A B兩個帶頭結點的非遞減單鏈表歸併為一個非遞增的有序單鏈表,不佔用額外空間*/
SLink *connect(SLink *ha,SLink *hb)
{
	SLink *pa=ha->next,*pb=hb->next,*hc,*tc;
	hc=pa;
	hc->next=NULL;
	tc=hc;//tc始終指向hc的最後一個結點

	while(pa!=NULL && pb!=NULL)
	{
		if(pa->data < pb->data)//將pa連結到tc之後
		{
			tc->next=pa;
			tc=pa;
			pa=pa->next;
		}
		else if(pa->data > pb->data)//將pb連結到tc之後
		{
			tc->next=pb;
			tc=pb;
			pb=pb->next;
		}
		else//將pa pb連結到tc之後
		{
			tc->next=pa;
			tc=pa;
			pa=pa->next;

			tc->next=pb;
			tc=pb;
			pb=pb->next;						
		}
	}
	tc->next=NULL;
	if(pa != NULL)//ha連結串列還有結點時
		tc->next=pa;
	if(pb != NULL)//hb連結串列還有結點時
		tc->next=pb;
	return hc;
}