數據結構之鏈表的基本操作

1、鏈表的概念:鏈表是一種非連續、非順序的數據結構。
2、鏈表的分類:主要分爲這三類:單鏈表、雙向鏈表、循環鏈表,這三者又可以通過組合形成總共8種鏈表。
3、鏈表的基本操作:

// 動態鏈表的基本操作:
//不帶頭節點的單鏈表 
typedef int SDataType;

// 節點結構 
typedef struct SListNode
{
SDataType _data;
struct SListNode* _pNext;
}Node;


// 給一個鏈表結構 
typedef struct SList
{
Node* _pHead;
}SList;


// 鏈表的初始化 
void SListInit(SList* pl){
assert(pl);
pl->_pHead = NULL;

}

// 在鏈表中尾插值爲data的節點 
void SListPushBack(SList* pl, SDataType data){
assert(pl);
Node* node = (Node*)malloc(sizeof(Node));
node->_data = data;

// 如果鏈表中只有一個結點
if (pl->_pHead == NULL){
	node->_pNext = NULL;
	pl->_pHead = node;
	return;
}

// 不止一個結點,先找到最後一個結點
Node* cur = pl->_pHead;
while (cur->_pNext != NULL){
	cur = cur->_pNext;
}
cur->_pNext = node;


}

// 刪除鏈表最後一個節點 
void SListPopBack(SList* pl){
assert(pl);

// 只有一個結點
if (pl->_pHead->_pNext == NULL){
	free(pl->_pHead);
	pl->_pHead == NULL;
}
// 不止一個結點

Node* cur = pl->_pHead;
while (cur->_pNext != NULL){
	cur = cur->_pNext;
}
free(cur->_pNext);
cur->_pNext = NULL;
}

// 在鏈表第一個元素前插入值爲data的節點 (頭插)
void SListPushFront(SList* pl, SDataType data){
assert(pl);
Node* node = (Node*)malloc(sizeof(Node));
node->_data = data;
node->_pNext = pl->_pHead;
pl->_pHead = node;

}

// 刪除鏈表中第一個節點 
void SListPopFront(SList* pl){
assert(pl);
Node* next = pl->_pHead->_pNext;
free(pl->_pHead);
pl->_pHead == next;
}

// 在鏈表pos位置後插入置爲data的節點 
void SListInsertAfter(Node* pos, SDataType data){
Node* node = (Node*)malloc(sizeof(Node));
node->_data = data;

node->_pNext = pos->_pNext;
pos->_pNext = node;
}


// 刪除pos後的結點

void SListEraseAfter(SListNode* pos){

Node* cur = pos->_pNext;
pos->_pNext = pos->_pNext->_pNext;
free(pos->_pNext);
free(cur);
}
// 刪除鏈表中值爲data的節點 
void SListErase(SList* pl, SDataType data){
// 鏈表爲空
if (pl == NULL){
	return;
}

// 是鏈表的第一個結點
if (pl->_pHead->_data == data){
	Node* next = pl->_pHead->_pNext;
	free(pl->_pHead);
	pl->_pHead = next;
	return;

}
// 遍歷
Node* cur = pl->_pHead;
while (cur->_pNext != NULL){
	if (cur->_pNext->_data == data){
		Node* next = cur->_pNext->_pNext;
		free(cur->_pNext);
		cur->_pNext = next;

	}
	cur = cur->_pNext;
}
}

// 在鏈表中查找值爲data的節點,找到返回該節點的地址,否則返回空 
Node* SListFind(SList* pl, SDataType data){
if (pl == NULL){
	return NULL;
}

if (pl->_pHead->_data == data){
	return pl->_pHead;
}
Node* cur = pl->_pHead;
while (cur->_pNext != NULL){
	if (cur->_pNext->_data == data){
		return cur->_pNext;
		cur = cur->_pNext;
	}
}
return NULL;
}

	// 銷燬鏈表 
void SListDestroy(SList* pl){

// 刪除所有結點
Node* cur = pl->_pHead;
Node* next = cur->_pNext;
while (cur->_pNext != NULL){
	next = cur->_pNext;
	free(cur);
}
pl->_pHead = NULL;

}

// 獲取鏈表中有效節點的個數 
int SListSize(SList* pl){
int count = 0;
Node* cur = pl->_pHead;
while (cur->_pNext != NULL){
	cur = cur->_pNext;
	count++;

}
return count;

}

// 檢測鏈表是否爲空 
int SListEmpty(SList* pl){
if (pl->_pHead == NULL){
	return 1;
}
else
	return 0;
}

// 獲取鏈表的第一個節點 
Node* SListFront(SList* pl){
assert(pl);
return pl->_pHead;

}

// 獲取鏈表的第二個節點 
Node* SListBack(SList* pl){
assert(pl);
return pl->_pHead->_pNext;

}

// 刪除鏈表中第一個值爲data的節點 
void SListRemove(SList* pl, SDataType data){
assert(pl);
Node* cur = pl->_pHead;
while (cur->_pNext != NULL){
	if (cur->_pNext->_data == data){
		Node* next = cur->_pNext->_pNext;

		free(cur->_pNext);
		cur = next;
		break;
	}
}
}

// 刪除鏈表中所有值爲data的節點 
void SListRemoveAll(SList* pl, SDataType data){
assert(pl);
Node* cur = pl->_pHead;
while (cur->_pNext != NULL){
	if (cur->_pNext->_data == data){
		Node* next = cur->_pNext->_pNext;

		free(cur->_pNext);
		cur = next;
		
	}
}
}

// 熟悉雙向鏈表的結構,並實現帶頭結點的雙向循環鏈表的以下基本操作:
typedef int DLDataType;

typedef struct DListNode
{
struct DListNode* _pNext;
struct DListNode* _pPre;
DLDataType _data;
}DLNode;



// 初始化雙向鏈表 
void DListInit(DLNode* pHead){
assert(pHead);
pHead->_pNext = NULL; 
pHead->_pPre = NULL;




}

// 尾插 
void DListPushBack(DLNode* pHead, DLDataType data){
assert(pHead);

DLNode* node = (DLNode*)malloc(sizeof(DLNode));
node->_data = data;

node->_pNext = pHead;
node->_pPre = pHead->_pPre;
pHead->_pPre->_pNext = node;

pHead->_pPre = node;


}

// 尾刪 
void DListPopBack(DLNode* pHead){
assert(pHead);
if (pHead->_pNext = pHead){

	return;

}
else{
	pHead->_pPre = pHead->_pPre->_pPre;
	free(pHead->_pPre->_pNext);
	pHead->_pPre->_pNext = pHead;

}
}

// 頭插 
void DListPushFront(DLNode* pHead, DLDataType data){
assert(pHead);
DLNode* node = (DLNode*)malloc(sizeof(DLNode));
node->_data = data;

node->_pNext = pHead->_pNext;
node->_pPre = pHead;

pHead->_pNext->_pPre = node;
pHead->_pNext = node;

}

// 頭刪 
void DListPopFront(DLNode* pHead){
assert(pHead);
DLNode* cur = pHead->_pNext;
pHead->_pNext->_pNext->_pPre = pHead;
pHead->_pNext = pHead->_pNext->_pNext;
free(cur);
cur = NULL;
}

// 在鏈表中查找值爲data的節點,找到返回節點的位置 
DLNode* DListFind(DLNode* pHead, DLDataType data){
assert(pHead);
DLNode* cur = pHead->_pNext;
while (cur != pHead){
	if (cur->_data == data){
		return cur;
	}
	cur = cur->_pNext;
}
return NULL;
}

// 在pos位置(插入成功後新節點實際在pos前)插入值爲data的元素 
void DListInsert(DLNode* pos, DLDataType data){
assert(pos);
DLNode* node = (DLNode*)malloc(sizeof(DLNode));
node->_data = data;

node->_pNext = pos;
node->_pPre = pos->_pPre;
pos->_pPre->_pNext = node;
pos->_pPre = node;

}

// 刪除pos位置的節點 
void DListErase(DLNode* pos){
assert(pos);

pos->_pNext->_pPre = pos->_pNext;
pos->_pPre->_pNext = pos->_pPre;
free(pos);
pos = NULL;
}

// 將鏈表中的所有節點清空 
void DListClear(DLNode* pHead){
assert(pHead);
DLNode* cur = pHead->_pNext;
while (cur != pHead){
	DLNode* next = cur->_pNext;
	cur->_pNext->_pPre = cur->_pPre;
	cur->_pPre->_pNext = cur->_pNext;
	free(cur);
	cur = next->_pNext;
}
}

// 銷燬鏈表 
void DListDestroy(DLNode** pHead){
assert(pHead);
DLNode* cur = *pHead;
cur = cur->_pNext;
while (cur != *pHead)
{
	DLNode* next = cur->_pNext;
	
	free(next);
}

free(*pHead);
*pHead = NULL;

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