【数据结构】线性表链式存储结构-单向链表

线性表的链式存储结构

  • 链表的存储结点包括数据域和指针域
  • 数据域存储相关信息,指针域存储地址
  • 使用带头结点的链表结构,具有如下优点:
  1. 首结点的插入和删除操作与其他结点一致,无需特别处理
  2. 无论链表是否为空都有一个头结点,统一了空表和非空表的处理,即判断L->next是否为空即可
  • 单向链表,双向链表,单向循环链表,双向循环链表一些基本操作是相同的,只是他们的类型不同,
    因此可以通过
typedef  x  LinkType
/*
 * x是链表的类型(例如单向链表结构,双向链表结构等),重新定义一个通用的类型:LinkType
 * 这样就可以通过LinkType来定义函数,对不同链表类型的移植和修改会更加方便
 */

单链表基本操作

//宏定义
#define FAILED		0
#define SUCCESS		1

typedef int ElemType;
typedef struct LNode
{
	ElemType data;
	struct LNode* next;
}LinkNode;

//创建链表
//**********************头插法**********************//
LinkNode* CreateLinkListF(ElemType a[], int n)
{
	LinkNode* L = (LinkNode*)malloc(sizeof(LinkNode));
	LinkNode* s;
	L->next = NULL;
	for (int i = 0; i < n; i++)
	{
		s = (LinkNode*)malloc(sizeof(LinkNode));
		s->data = a[i];
		s->next = L->next;
		L->next = s;
	}
	return L;
}

//**********************尾插法**********************//
LinkNode* CreateLinkListR(ElemType a[], int n)
{
	LinkNode* L = (LinkNode*)malloc(sizeof(LinkNode));
	LinkNode* r = L;
	LinkNode* s;
	for (int i = 0; i < n; i++)
	{
		s= (LinkNode*)malloc(sizeof(LinkNode));
		s->data = a[i];
		r->next = s;
		r = s;
	}
	r->next = NULL;
	return L;
}


//**********************链表初始化**********************//
LinkNode* InitLinkList()
{
	LinkNode* L = (LinkNode*)malloc(sizeof(LinkNode));
	L->next = NULL;
	return L;
}

//**********************销毁线性表**********************//
void DestroyLinkList(LinkNode* L)
{
	LinkNode* s = L;
	LinkNode* next = L->next;
	while (next )
	{
		free(s);
		s = next;
		next = next->next;
	}
	free(s);
}

//**********************判断空表**********************//
int LinkListEmpty(LinkNode* L)
{
	return (L->next == NULL);
 }

//**********************求表长**********************//
int LinkListLength(LinkNode* L)
{
	int n = 0;
	LinkNode* s = L;
	while (s->next)
	{
		n++;
		s = s->next;
	}
	return n;
}

//**********************输出信息**********************//
void DispLinkList(LinkNode* L)
{
	LinkNode* s = L->next;
	s = L->next;
	while (s)
	{
		printf("%d  ", s->data);
		s = s->next;
	}
	printf("\n");
}

//**********************得到第i个值**********************//
int GetLinkElem(LinkNode* L, int i, ElemType* e)
{
	LinkNode* s = L->next;
	if (i < 0) return FAILED;
	int n = 1;
	while (n < i && s)
	{
		n++;
		s = s->next;
	}
	if (!s) return FAILED;
	else
	{
		*e = s->data;
		return SUCCESS;

	}
}

//**********************得到e的索引**********************//
int LocateLinkElem(LinkNode* L, ElemType e)
{
	LinkNode* s = L;
	int i = 1;
	while (s->next && s->data != e)
	{
		s = s->next;
		i++;
	}
	if (s->next == NULL) return FAILED;
	else return i;

}

//**********************插入元素**********************//
int LinkListInsert(LinkNode* L, int i, ElemType e)
{
	if (i <= 0) return FAILED;
	LinkNode* s = L;
	LinkNode* r;
	int n = 1;
	while (n < i && s )
	{
		s = s->next;
		n++;
	}
	if (!s) return FAILED;
	else
	{
		r = (LinkNode*)malloc(sizeof(LinkNode));
		r->data = e;
		r->next = s->next;
		s->next = r;
		return SUCCESS;
	}
	
}

//**********************删除元素**********************//
int LinkListDelete(LinkNode* L, int i, ElemType* e)
{
	if (i <= 0) return FAILED;
	LinkNode* s = L;
	LinkNode* q;
	int n = 1;
	while ( n < i && s->next)
	{
		s = s->next;
		n++;
	}
	if (s->next == NULL) return FAILED;
	else
	{
		q = s->next;
		s->next = q->next;
		free(q);
		return SUCCESS;
	}
}

单链表应用实例

//将一个带头结点的单链表L分成两个单链表L1和L2,其中L1使用L的单链表,单数位属于L1,双数位属于L2
void SplitLink(LinkNode* L,LinkNode** L1,LinkNode** L2)
{
	LinkNode* r = L;
	LinkNode* p= L->next;
	*L1 = L;
	*L2 = (LinkNode*)malloc(sizeof(LinkNode));
	(*L2)->next = NULL;
	while (p)
	{
		r->next = p;
		r = p;
		if (!p->next)
			break;
		p = p->next->next;
		r->next->next = (*L2)->next;
		(*L2)->next = r->next;
	}
	r->next = NULL;
}


//删除单链表L中的元素值最大的一个结点
void DelMaxLinkNode(LinkNode* L)
{
	LinkNode* pre=L;
	LinkNode* p = L->next;
	LinkNode* max = L->next;
	LinkNode* preMax = L;
	while (p)
	{
		if (max->data < p->data)
		{
			max = p;
			preMax = pre;
		}
		pre = p;
		p = p->next;
	}
	preMax->next = max->next;
	free(max);
}

//将一个带头结点和至少一个数据结点的单链表进行有序递增排序
void SortLink(LinkNode* L)
{
	LinkNode* pre = L;
	LinkNode* p;
	LinkNode* q;
	p = L->next->next;
	L->next->next = NULL;	
	while (p)
	{
		q = p->next;
		pre = L;
		while (pre->next && pre->next->data < p->data)
			pre = pre->next;
		p->next = pre->next;
		pre->next = p;
		p = q;
	}
}

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章