数据结构入门:无头单向不循环链表的实现

  1. 链表是一种物理存储结构上非连续、非顺序的存储结构,数据元素的逻辑顺序是通过链表中指针的连接次序实现的。
  2. 在8中链表中,常用的有两种:无头单向不循环链表和带头循环双向链表。
  3. 首先,无头单项不循环链表的结构简单,但是一般不用来存储数据,实际中更多的是作为其他数据结构的子结构,比如:哈希桶、图的邻接表等;
  4. 下面是其增删查改等操作的代码实现:
typedef int SLDataType;
/结点(数据和指向下一个结点的指针,其类型为结点指针)
typedef struct SListNode{
	SLDataType _data;
	struct  SListNode* _next;
}SListNode;
/单链表(链表的起点:不是头结点,头结点不占空间)
typedef struct SList{
	SListNode* _head;
}SList;

void SListInit(SList* plist){
	assert(plist);
	plist->_head = NULL;
}

/当链表的起点存在时就要开始删除(要记录每次删除结点的下一个结点)
void SListDestory(SList* plist){
	assert(plist);
	while (plist->_head){
		SListNode* tNode = plist->_head->_next;
		free(plist->_head);
		plist->_head = tNode;
	}
}

SListNode* BuySListNode(SLDataType x){
	SListNode* newNode = (SListNode*)malloc(sizeof(SListNode));
	assert(newNode);
	newNode->_data = x;
	newNode->_next = NULL;
	return newNode;
}

/链表头插(如果当前链表不为空,就把新结点当做链表的起点,
/原链表的起点就变成了链表的第二个结点)
void SListPushFront(SList* plist, SLDataType x){
	assert(plist);
	SListNode* newNode = BuySListNode(x);
	assert(newNode);
	if (plist->_head == NULL){
		plist->_head = newNode;
		return;
	}
	else{
		newNode->_next = plist->_head;
		plist->_head = newNode;
	}
}

void SListPopFront(SList* plist){
	assert(plist);
	SListNode* tNode = plist->_head->_next;
	free(plist->_head);
	plist->_head = tNode;
}


//尾插:无结点
//已经有结点(找到最后一个结点再插入新结点)
void SListPushBack(SList* plist,SLDataType x){
	assert(plist);
	SListNode* newNode = BuySListNode(x);
	assert(newNode);
	if (plist->_head == NULL){
		plist->_head = newNode;
	}
	else{
		SListNode* tail = plist->_head;
		while (tail->_next){
			tail = tail->_next;
		}
		tail->_next = newNode;
	}
}

/尾删:有一个结点;
/有多个结点:要记录倒数第二个结点的位置
void SListPopBack(SList* plist){
	assert(plist->_head);
	SListNode* tail = plist->_head;
	if (tail->_next == NULL){
		free(tail);
		plist->_head = NULL;
	}
	while (tail->_next->_next!=NULL){
		tail = tail->_next;
	}
	free(tail->_next);
	tail->_next = NULL;
}

SListNode* SListFind(SList* plist, SLDataType x){
	    assert(plist);
		SListNode* tNode = plist->_head;
		while (tNode != NULL){
			if (tNode->_data != x){
				tNode = tNode->_next;
			}
			else{
				return tNode;
			}
		}
		return -1;	
}

/在pos的后面插入结点(pos位置不存在;pos在头上;pos在后边)
void SListInsertAfter(SList*plist,SListNode* pos, SLDataType x){
	assert(plist);
	SListNode* newNode = BuySListNode(x);
	assert(newNode);
	if (pos == -1){
		return - 1;
	}
	else if (pos == plist->_head){
		SListPushFront(plist,x);
	}
	else{
		SListNode* tNode = plist->_head->_next;
		while (tNode != pos){
			tNode = tNode->_next;
		}
		tNode = pos->_next;
		pos->_next = newNode;
		newNode->_next = tNode;
	}
}

/在pos的后面删除结点
void SListEraseAfter(SList*plist, SListNode* pos){
	assert(plist);
	if (pos == -1){
		return -1;
	}
	else if (pos == plist->_head){
		SListPopFront(plist);
	}
	else{
		SListNode* tNode = plist->_head->_next;
		while (tNode != pos){
			tNode = tNode->_next;
		}
		SListNode* cur = tNode->_next;
		SListNode* tail = tNode->_next->_next;
		free(cur);
		tNode->_next = tail;
	}
}

/删除链表中的值为X的元素
void SListRemove(SList* plist, SLDataType x){
	assert(plist);
	SListNode* bNode = plist->_head;
	if (bNode->_data == x){
		SListNode* cur = bNode;
		free(bNode);
		cur->_next = plist->_head;
		return;
	}
	else{
		SListNode* tNode = plist->_head->_next;
		while (tNode->_data != x){
			bNode = bNode->_next;
			tNode = tNode->_next;
		}
		SListNode* eNode = tNode->_next;
		free(tNode);
		bNode->_next = eNode;
	}
}

/打印的时候,不能直接用plist->_head直接遍历,会改变头指针的位置。
void SListPrint(SList* plist){
	assert(plist);
	SListNode* head = plist->_head;
	while (head->_next){
		printf("%d->", head->_data);
		head = head->_next;
	}
	printf("%d\n", head->_data);
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值