数据结构之链表的基本操作

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;

}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值