線性結構總結

zzzzzt1發表於2020-11-05

線性結構

(一)線性表

它不僅僅是陣列或者連結串列,它是一個結構體,結構體裡面包含有資料陣列和線性表的大小。

順序儲存

使用陣列進行儲存
1)首先需要定義一個結構體,包含資料陣列和線性表的大小(使用last作為標記)。

注意事項:
1、初始化線性表就是為它開闢一片空間。
2、PtrL->last中的->針對指向結構體的指標,而成員訪問符.是針對於結構體變數。
3、在進行插入操作的時候應該考慮到原本的空間是否已經滿、插入的位置是否合法。
4、並且增加和刪除元素之後,記得更新last的值。

//線性表的順序儲存結構//

//建立之前需要建立一個結構體//
typedef struct LNode *List; 
struct LNode{//整個線性表被包含在這個結構體中// 
	Elementype Data[MAXSIZE];
	int last//用於儲存順序表的大小// 
}L;

List PtrL;//用PtrL指向結構體// 

//操作一:建立一個順序表,初始化//
List MakeEmpty()
{
	PtrL=(List)malloc(sizeof(struct LNode));
	PtrL->last=-1;
	return PtrL;
}

//操作二:查詢元素//
int Find(int X;List PrtL)
{
	int i=0;
	while(i<=PtrL->last&&PtrL->Data[i]!=X) 
	{
		i++;
	}
	if(i>PtrL->last)
		return -1;
	else 
		return i;	
}

//操作三:插入——先移動再插入//
void Insert(int X,int i,List PrtL)//在第i個位置插入X
{
	if(PrtL->last==MAXSIZE-1)
	{ 
		pritnf("表已經滿了");
		return;
	}
	if(i<1||i>PrtL->last+2)//判斷插入的位置是否合法
	{
		printf("位置不合法");
		return; 
	}
	int j;
	for(j=PrtL->last;j>=i-1;j--)
	{
		PrtL->Data[j+1]=PrtL->Data[j];
	}
	PrtL->Data[i-1]=X;
	PrtL->last++;
	return;
} 

//操作四:刪除元素//
void Delete(int i,List PrtL)//刪除第i個位置的元素// 
{
	if(i<1||i>PrtL->last+1)
	{
		printf("不存在第i個元素")
		return; 
	}
	int j;
	for(j=i-1;j<=PrtL->last;j++)
	{
		PrtL->Data[i-1]=PrtL->Data[i];
	}
	PrtL->last--;//刪完之後別忘了將last值減去 // 
	return;
} 

鏈式儲存

使用連結串列進行儲存
1)仍然需要定義一個結構體,裡面包含資料和指向下一個結點的指標。

注意事項:
1、對於一切插入操作,首先應想到插入內容的本質,比如插入結點,那麼首先就得構建一個結點,分配空間。
2、對於連結串列,插入的位置有區別,連結串列頭和其他位置有不同,需單獨考慮。
3、在進行刪除操作的時候也應該注意表頭和其他位置的不同,並且需要有一個指標指向被刪除的結點,然後 free。

//線性表的鏈式儲存結構//
typedef struct LNode *List;
struct LNode{
	int data;
	List next;
}L;
List PrtL;
//因為是自定義型別,List本身就是一個指向結點的指標所以不是*PrtL 

//操作一:求表長//
int length(List PrtL)
{
	int i=0;
	List p=PrtL;//p指向表中的第一個結點// 
	while(PrtL!=NULL)
	{
		i++;
		PrtL=PrtL->next;	
	}
	return i; 
}

//操作二:查詢//
//按照序號查詢//
List FindKth(int K,List PrtL) 
{
	List p=PrtL;
	int i=0;
	while(i<k&&p!=NULL)
	{
		i++;
		p=p->next;
	}
	if(i==k)
		return p;
	else
		return NULL;
}

//按照值查詢//
List Find(ElementType X,List PrtL)
{
	List p=PrtL;
	while(p)
	{
		if(p->data==X)
			return p;
		p=p->next;
	}
	return NULL;
} 

//操作三:插入//
List Insert(ElementType X,int i,List PrtL)//在第i個位置插入元素X//
{
	List s=malloc(sizeof(struct LNode));//構建預插入結點// 
	s->data=X;
	
	if(i==1)
	{
		s->next=PrtL;
		return s;
	}
	
	List p=PrtL;//指向第一個結點// 
	int j=0;
	while(j<i-2)
	{
		j++;
		p=p->next;
		if(!p)
			return NULL;
	}
	s->next=p->next;
	p->next=s;
	return PrtL;
} 

//操作四:刪除//
List Delete(int i,List PrtL)
{
	List p,s;
	if(i==1)//如果是刪除第一個結點// 
	{
		List s=PrtL;
		if(!PrtL)
			return NULL;
		else
			PrtL=PrtL->next;
		free(s);//一定要有free的操作// 
		return  PrtL;
	}

	p=FindKth(i-1,PrtL);
	if(!p)
		return NULL;
	else if(!p->next)
		return NULL;
	else
	{
		s=p->next;//首先將結點定位好// 
		p->next=s->next;
		free(s);
		return PrtL;
	}	
} 

(二)堆疊

與線性表一樣,堆疊也是一個結構體,裡面包含一個一維陣列和儲存棧頂元素位置的變數。

順序儲存

使用陣列進行堆疊的儲存

注意事項:
1、在使用堆疊的時候應當先進行初始化操作。
2、入棧相當於插入,所以應判斷堆疊是否滿了。
3、出棧相當於刪除,應判斷刪除的元素是否合法,也就是是否堆疊是空的。
4、遇到先pop出來top標記再減掉的情況可以,寫在同一個表示式中。

//堆疊的順序儲存結構//
typedef struct SNode *Stack;
struct SNode{
	ElementType Data[MAX];
	int top; 
};

//操作一:入棧//
void Push(Stack PrtS,ElementType item){
	
	PrtS=malloc(sizeof(struct SNode));
	PrtS->top=-1;//初始化堆疊//
	
	if(PrtS->top==MAX-1)
	{
		printf("堆疊已滿")return; 
	}
	else
	{
		PrtS->Data[++(PrtS->top)]=item;
		return;
	} 
}

//操作二:出棧//
ElementType Pop(Stack PrtS){
	if(PrtS->top==-1)
		return ERROR;
	else
		return PrtS->Data[(PrtS->top)--]; 
} 

鏈式儲存

使用連結串列進行儲存
1)同樣使用結構體,但是結構體裡面儲存的就是資料和指向下一節點的指標,不是資料陣列。

注意事項:
1、結點或者連結串列在進行初始化的時候應當將next指標置為NULL。
2、堆疊的鏈式儲存top指標應該放在表頭,head和第一個資料節點之間,top如果放在尾端,則刪除的時候無法找到前端指標。

//堆疊的鏈式儲存結構//
typedef struct SNode *Stack;
struct SNode{
	ElementTpye Data;
	Stack next;
};  

//操作一:初始化//
Stack Creat(){
	Stack S;//指向結點//
	S=malloc(sizeof(struct SNode));
	S->next=NULL;
	return S;
}

//操作二:判斷是否為空//
int IsEmpty(Stack S){
	return (S->next==NULL);//為空的話就返回整數1// 
}

//操作三:入棧//
void Push(ElementType X,Stack S){
	struct SNode New=malloc(sizeof(struct SNode));
	New->Data=X;
	New->next=NULL;//初始化結點//
	
	New->next=S->next;
	S->next=New;
	return;
}

//操作四:出棧//
ElementType Pop(Stack S){
	struct SNode *Delete;//刪除元素,需要釋放空間,則需要定義一個指標// 
	if(!S->next)
		return ERROR;
	else
	{
		Delete=S->next;
		S->next=Delete->next;
		free(Delete);
		return Delete->Data;
	}
}

(三)佇列

同樣使用結構體包裝整個佇列

順序儲存

使用陣列儲存,結構體中包含一個一維陣列和front和rear標記

//佇列的順序儲存//
typedef struct QNode *Queue;
struct QNode{
	ElementType Data[MAX];
	int front;
	int rear;
};

//操作一:初始化//
Queue creat(){
	Queue Q=malloc(sizeof(struct QNode));
	front=-1;
	rear=-1;
	return Q;
}

//操作二:入隊,出隊//
void Add(Queue PtrQ,ElementType item){
	if("佇列滿了")
		return;
	else
		PtrQ->Data[++(PtrQ->rear)]=item;
} 

ElementType Pop(Queue PtrQ){
	if(PtrQ->front==PtrQ->rear)
	{
		printf("佇列是空的");
		return; 
	}
	else
		return PtrQ->Data[(PtrQ->front)++];
}

鏈式儲存

鏈式儲存需要兩個結點,資料結點包含資料和指向下一結點指標,另一結點包含front和rear指標。
注意事項:
1、鏈式儲存時front和rear分別位於表頭和表尾,因為表頭方便刪除。

//佇列的鏈式儲存結構//
struct Node{
	ElementType data;
	struct Node *next;
};
struct QNode{
	struct Node *front;
	struct Node *rear;
};
typedef struct Node *Queue

//操作一:出隊(無頭結點)//
ElementType Delete(Queue PrtQ){
	struct Node *pop;
	pop=QNode->front;
	if("佇列為空")
		return EORROR;
	else
	{
		pop->data=QNode->front->data;
		QNode->front=QNode->front->next;
		free(pop);
		return pop->data;
	} 
} 

相關文章