線性表的鏈式存儲結構
- 鏈表的存儲結點包括數據域和指針域
- 數據域存儲相關信息,指針域存儲地址
- 使用帶頭結點的鏈表結構,具有如下優點:
- 首結點的插入和刪除操作與其他結點一致,無需特別處理
- 無論鏈表是否爲空都有一個頭結點,統一了空表和非空表的處理,即判斷L->next是否爲空即可
- 單向鏈表,雙向鏈表,單向循環鏈表,雙向循環鏈表一些基本操作是相同的,只是他們的類型不同,
因此可以通過
typedef x 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");
}
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;
}
}
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;
}
}
單鏈表應用實例
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;
}
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;
}
}