【數據結構】線性錶鏈式存儲結構-單向鏈表

線性表的鏈式存儲結構

  • 鏈表的存儲結點包括數據域和指針域
  • 數據域存儲相關信息,指針域存儲地址
  • 使用帶頭結點的鏈表結構,具有如下優點:
  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;
	}
}

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