說明
1.有頭結點的單鏈表的9中運算;
2.因爲網上的寫法與書上的多少有點兒出入,所以我就自己寫了一遍常用的9中運算,如果想要不帶頭結點的運算,你可以在相應的運算中加一個 if 判斷,然後把沒有頭結點的情況列進去就行啦!
代碼
#include<stdio.h>
#include<stdlib.h>
#define OK 1
#define ERROR 0
typedef int Status;
typedef int ElemType;
typedef struct LNode
{
ElemType data;
LNode *next;
}LNode, *LinkList;
Status InitList(LinkList &L)
{ // 初始化
L = (LinkList)malloc(sizeof(ElemType));
if(!L) return ERROR; // 分配內存失敗
L->next = NULL;
return OK;
}//InitList
Status DispList(LinkList &L)
{ // 打印單鏈表
LinkList p = L;
p = p->next;
while(p)
{
printf("%d\t", p->data);
p = p->next;
}
return OK;
}//DispList
Status ListLength(LinkList &L)
{ // 獲取單鏈表的長度
int i = 0;
LinkList p = L;
while(p->next)
{
p = p->next;
i ++;
}
return i;
}//ListLength
Status GetElem(LinkList &L, int i, LinkList e)
{ // 用 e 返回 L 中第 i 個元素的值
LinkList p = L;
for(int j = 0; j < i; j++)
p = p->next;
e = p;
return e->data;
}//GetElem
Status ListInsert(LinkList &L, int i, int e)
{ // 在表 L 的第 i 個元素之前(邏輯位序與物理位序差 1 )插入新元素 e
LinkList p, temp, x;
int j = 0;
p = L;
if(i < 1 || i > ListLength(L)-1) return ERROR; // 非法插入
while(p && j < i-1)
{
p = p->next;
j++;
}
temp = (LinkList)malloc(sizeof(LNode));
if(!temp) return ERROR;
temp->data = e;
temp->next = p->next;
p->next = temp;
return OK;
}//ListInsert
Status DestroyList(LinkList &L)
{ // 銷燬單鏈表
LinkList p;
while(L) // 如果單純的 free(L) 就只是釋放了頭結點的內存空間,會造成內存碎片
{
p = L->next;
free(L);
L = p;
}
return OK;
}//Destroy
Status ListEmpty(LinkList &L)
{ // 判斷單鏈表是否爲空
return L->next == NULL;
}//ListEmpty
Status LocateElem(LinkList &L, ElemType e)
{ // 返回 L 中第一個與 e 相等的元素的邏輯位序
int i = 0;
LinkList p;
p = L->next;
while(p->data != e)
{
if(p)
{
printf("\n該元素不在本鏈表中!\n");
return ERROR;
break;
}
p = p->next;
i ++;
}
return i;
}//LocateElem
Status ListDelete(LinkList &L, int i, ElemType e)
{ // 刪除表 L 中 第 i 個元素
// 注:1 <= i <= n
int j = 0;
LinkList p, q;
p = L;
if(i < 1 || i > ListLength(L)-1) return ERROR; // 非法插入
while(p->next && j < i-1)
{
p = p->next;
j++;
}
q = p->next;
p->next = q->next;
e = q->data;
free(q);
printf("\n刪除的元素爲:%d\n", e);
return OK;
}//ListDelete
int main()
{
int choice = 1, i, temp;
LinkList L, e;
printf("請輸入序號進行相應的操作:\n");
while(choice != 0)
{
printf("\n1.InitList 2.ListLength 3.DispList 4.GetElem 5.LocateElem \n6.ListInsert 7.ListDelete 8.ListEmpty 9.Destroy 0.exit\n");
scanf("%d", &choice);
switch (choice)
{
case 1:
if(InitList(L))
printf("\n初始化單鏈表成功!\n");
break;
case 2:
if(ListEmpty(L))
printf("\n單鏈表爲空\n");
else
printf("\n單鏈表的長度爲:%d\n", ListLength(L));
break;
case 3:
if(ListEmpty(L))
printf("\n單鏈表爲空\n");
else
{
printf("\n單鏈表爲:\n");
DispList(L);
}
break;
case 4:
if(!ListEmpty(L))
{
printf("\n請輸入想要 get 的元素的邏輯位序:");
scanf("%d", &i);
GetElem(L, i, e);
}
else
printf("\n單鏈表爲空,你在無中生有、暗度陳倉....\n");
break;
case 5:
if(ListEmpty(L))
printf("\n單鏈表爲空,你找個錘兒!\n");
else
{
printf("\n請輸入想要查找的元素:\n");
scanf("%d", &temp);
LocateElem(L, temp);
}
break;
case 6:
printf("\n請輸入想要插入的位置和想要插入的元素(中間用空格隔開):\n");
scanf("%d %d", &i, &temp);
// scanf("%d", &temp);
if(ListInsert(L, i, temp))
printf("\n插入成功!\n");
else
printf("\n插入失敗!\n");
break;
case 7:
if(ListEmpty(L))
printf("\n單鏈表爲空!\n");
else
{
printf("\n請輸入想要刪除的元素的位置:\n");
scanf("%d", &i);
ListDelete(L, i, temp);
}
break;
case 8:
if(ListEmpty(L))
printf("\n單鏈表爲空!\n");
else
printf("\n有內容!不爲空!\n");
break;
case 9:
if(DestroyList(L))
printf("\n銷燬成功\n");
else
printf("\n銷燬失敗!\n");
break;
case 0:
choice = 0;
break;
default:
printf("\n程序出錯!\n");
break;
}
}
DestroyList(L); // 養成用完就銷燬的好習慣,不給電腦增加負擔!
return 0;
}
運行結果示意圖就不貼出來啦,因爲用的不是 CreateList() 函數生成的單鏈表,而是 ListInsert() 函數一個一個插入的,這樣的話結果會比較長,我也不會截取長圖....抱歉....
THE END!