1. 程式人生 > >連結串列(C語言)刪除、插入(頭插法)、清空等操作

連結串列(C語言)刪除、插入(頭插法)、清空等操作

幾個重要知識點: 一:

L = (LinkList)malloc(sizeof(LNode));
	L->next = NULL;

在給節點分配記憶體後,一定要將next指標賦值為null。 二:

Status ListInsert(LinkList &L, int i, ElemType e)

為什麼有些函式引數前帶&號? 答:&是取地址的意思,傳遞變數的指標,使形參得到一個變數的地址,這時形參指標變數指向實參變數單元。如果我們在函式中對帶有&號的變數進行更改,那麼主函式相應變數的值也會隨之更改。 三:

typedef struct LNode {
	ElemType data;
	struct LNode *next;
}LNode,*LinkList;

定義節點時,LNode* p 和 LinkList p 的意思是一樣的。 四:

Status ClearList(LinkList &L)//清除連結串列的資料,連結串列的頭還在,可以繼續插入節點
{
	LNode *p = L->next;//p指向頭結點的下一個節點
	LNode *q;//q為哨兵
	if (L == NULL)return ERROR;
	while (p!=NULL)
	{
		q = p->next;//q指向p的下一個節點
		free(p);   //清除p
		p = q;		//再將p指向q
	}
	L->next = NULL;
	return OK;
}

迴圈體為什麼不能寫成 free§;p=p->next呢? 答:這樣寫是錯的,p指標的資料域和指標域已經被釋放了,不存在p=p->next。 清空操作先保留了連結串列的頭,然後把頭後面的所有的都銷燬,最後把頭指標的指標域指向NULL,這樣就相當與清空了,但這個連結串列還在,還可以繼續使用;保留了頭,後面的全部釋放。

程式碼如下:

#include<stdio.h>
#include<stdlib.h>
#define TRUE 1;
#define FALSE 0;
#define OK 1;
#define ERROR 0;
#define OVERFLOW -2;
typedef int Status;
typedef int ElemType;
typedef struct LNode {
	ElemType data;
	struct LNode *next;
}LNode,*LinkList;
void CreateList(LinkList &L,int n)
{
	L = (LinkList)malloc(sizeof(LNode));
	L->next = NULL;
	for (int i= n; i>0; i--)
	{
		LNode *p = (LinkList)malloc(sizeof(LNode));
		scanf_s("%d",&p->data);
		p->next = L->next;
		L->next = p;
	}
}
Status ListInsert(LinkList &L, int i, ElemType e)//在頭節點的單鏈線性表中第i個位置之前插入元素e
{
	LinkList p = L;
	int j = 0;
	while (p&&j<i-1)//尋找第i-1個節點
	{
		p = p->next;
		++j;
	}
	if (!p || j > i - 1) return ERROR;
	LNode *s = (LinkList)malloc(sizeof(LNode));//生成新節點
	s->data = e;
	s->next = p->next;    //插入L中,p的地址就是L的地址,插入p相當於插入L
	p->next = s;
	return OK;
}
void OutputList(LinkList L)
{
	LNode *p = L->next;
	while (p)
	{
		printf("%d\n",p->data);
		p = p->next;
	}
}
Status GetElem(LinkList L,int i,ElemType &e)
{
	LNode *p = L->next;		//初始化p指向第一個節點
	int j = 1;				//計數器,計算查詢次數
	while (p&&j<i)			//順時針向後查詢,直到p指向第i個元素或p為空
	{
		p = p->next;
		++j;
	}
	if (!p || j > i) return ERROR;
	e = p->data;
	return OK;
}
Status ListDelete(LinkList &L, int i, ElemType &e)//在帶頭結點的單鏈線性表L中刪除第i個元素,並用e返回其值
{
	LinkList p = L;
	int j = 0;
	while (p->next&&j < i - 1)//尋找第i個節點
	{
		p = p->next;
		++j;
	}
	if (!(p->next) || j > i - 1) return ERROR;//刪除位置不合理
	LNode *q = p->next;
	p->next = q->next;
	e = q->data;
	free(q);//釋放q節點
}
Status ClearList(LinkList &L)//清除連結串列的資料,連結串列的頭還在,可以繼續插入節點
{
	LNode *p = L->next;//p指向頭結點的下一個節點
	LNode *q;//q為哨兵
	if (L == NULL)return ERROR;
	while (p!=NULL)
	{
		q = p->next;//q指向p的下一個節點
		free(p);   //清除p
		p = q;		//再將p指向q
	}
	L->next = NULL;
	return OK;
}
Status ListLength(LinkList L)//求連結串列表長
{
	LNode *p = L->next;
	int j = 0;
	while (p)
	{
		p = p->next;
		j++;
	}
	return j;
}
int main()
{
	LinkList L;
	CreateList(L,4);
	printf("表中的元素依次為:\n");
	OutputList(L);
	ElemType e;
	GetElem(L,2,e);
	printf("第二個元素為:%d\n",e);
	printf("將101插入表中第二個位置:\n");
	ListInsert(L,2,101);
	OutputList(L);
	printf("刪除第三個元素:\n");
	ListDelete(L,3,e);
	OutputList(L);
	printf("連結串列長度為:%d\n",ListLength(L));
	ClearList(L);
	printf("清除資料後的連結串列長度為:%d\n", ListLength(L));
	system("pause");
}

程式碼參考《資料結構》(C語言)嚴蔚敏版,轉載請標明出處。