数据结构 链表 1(无头单链表)

1.什么是链表
链表也是线性表的一种,他在逻辑结构上是连续的,但是在物理结构上是非顺序连接的,通过指针连接而在逻辑上成为线性表

那么链表有什么好处呢,首先在顺序表中,删除或者插入一个元素,需要把删除或者插入位置之后的元素往后移动一位,然后再操作,时间复杂度是O(n),但是在链表中,插入或者删除的操作只用断开连接链表就可以了.

链表分为单向,双向 ,带头节点,不带头节点,循环和非循环

下面就来看无头单链表的相关操作

#include<stdio.h>
#include<windows.h>
#include<assert.h>

typedef int SDataType;
//节点结构体
typedef struct SListNode {
	SDataType data;
	struct SListNode* pNext;
}Node, *PNode;

//链表结构体
typedef struct SList {
	PNode pHead;
}SList,*PSList;

//创建一个新节点

PNode BuyNewNode(SDataType data) {
	PNode ptr = NULL;
	ptr = (PNode)malloc(sizeof(SDataType)+sizeof(PNode));
	if (NULL == ptr) {
		return NULL;
	}
	ptr->data = data;
	ptr->pNext = NULL;
	return ptr;
}

//链表初始化
void SListInit(SList* s) {
	assert(s);
	s->pHead = NULL;
}

//尾插
void SListPushBack(SList* s, SDataType data){
	PNode PCur = NULL;//指向当前节点
	assert(s);
	//如果链表空,就加入新节点
	if (s->pHead == NULL) {
		s->pHead = BuyNewNode(data);
		return;
	}
	PCur = s->pHead;
	while (PCur->pNext) {
		PCur = PCur->pNext;
	}
	PCur->pNext = BuyNewNode(data);
}

//尾删
void SListPopBack(SList* s) {
	assert(s);
	PNode PPre;//上一个节点
	PNode PCur;//当前节点
	PPre = s->pHead;
	PCur = s->pHead;
	//链表空
	if (NULL == s->pHead) {
		return;
	}
	if (PCur->pNext==NULL) {
		free(s->pHead);
		s->pHead = NULL;
		return;
	}
	//一个以上节点
	while (PCur->pNext) {
		PPre = PCur;
		PCur = PCur->pNext;
	}
	free(PPre->pNext);
	PPre->pNext = NULL;
}

//头插
void SListPushFront(SList* s, SDataType data) {
	assert(s);
	PNode PCur = NULL;//当前
	//链表空
	if (NULL == s->pHead) {
		s->pHead= BuyNewNode(data);
		return;
	}
	PCur = s->pHead;
	s->pHead = BuyNewNode(data);
	s->pHead->pNext = PCur;
}
 //头删
void SListPopFront(SList* s) {
	assert(s);
	PNode pre = NULL;
	if (NULL == s->pHead) {
		return;
	}
	if (s->pHead->pNext == NULL) {
		free(s->pHead);
		s->pHead = NULL;
	}
	pre = s->pHead;
	s->pHead = s->pHead->pNext;
	free(pre);
}

// 在链表的pos位置后插入值为data的节点
void SListInsert(SList* s,PNode pos, SDataType data) {
	assert(s);

	if (NULL == s->pHead) {
		if (pos == s->pHead) {
			s->pHead = BuyNewNode(data);
			return;
		}
		else {
			return;
		}
	}
	if (pos = s->pHead) {
		SListPushFront(s, data);
	}
	else {
		PNode cur = NULL;
		PNode pNewNode = BuyNewNode(data);
		if (pos== NULL) {
			free(pNewNode);
			return;
		}

		else {
			while (cur) {
				if (pos==cur)
				pos->pNext = pNewNode->pNext;
				pos->pNext = pNewNode;
			}
			cur = cur->pNext;
		}
	}
	return;
}

// 删除链表s中pos位置的节点 
void SListErase(SList* s, PNode pos) {
	assert(s);
	PNode pre = s->pHead;
	if (s->pHead == NULL) {
		return;
	}
	if (s->pHead == pos) {
		SListPopFront(s);
	}
	while ( (pre->pNext) != pos ) {
		pre = pre->pNext;//pre是pos前一个
	}
	pre->pNext = pos->pNext;
	free(pos);
}

// 在链表中查找值为data的节点,找到返回该节点的地址,否则返回NULL 
PNode SListFind(SList* s, SDataType data) {
	assert(s);
	PNode cur = s->pHead;
	while (cur) {
		if (cur->data == data){
			return cur;
			continue;
		}
	}
}


// 获取链表中有效节点的个数 
size_t SListSize(SList* s) {
	assert(s);
	size_t count = 0;
	if (s->pHead == NULL) {
		return 0;
	}
	while (s->pHead->pNext) {
		count += 1;
	}
	return count;
}

// 检测链表是否为空 
int SListEmpty(SList* s) {
	assert(s);
	if (s->pHead == NULL){
		return 1;
	}
	else{
		return 0;
	}
}

// 将链表中有效节点清空 
void SListClear(SList* s) {
	assert(s);
	if (s->pHead == NULL) {
		return;
	}
	else {
		s->pHead == NULL;
	}
}

//销毁链表

void SListDestroy(SList* s) {
	assert(s);
	s->pHead = NULL;
	free(s->pHead);
}

猜你喜欢

转载自blog.csdn.net/nihuhui666/article/details/89514527
今日推荐