欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页

单链表(不带头)

程序员文章站 2024-03-21 14:44:58
...

slist.h

#pragma once
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <assert.h>
//不带头链表
typedef int SDataType;
// 链表的节点 
typedef struct SListNode
{
	SDataType _data;
	struct SListNode* _pNext;
}Node, *PNode;
// 链表的结构,给一个头指针保存链表第一个节点的地址 
typedef struct SList
{
	PNode _pHead; // 指向链表中的第一个节点 
}SList, *PSList;
// 链表的初始化 
void SListInit(SList* s);
// 在链表s最后一个节点后插入值为data的节点 
void SListPushBack(SList* s, SDataType data);
// 删除链表s最后一个节点 
void SListPopBack(SList* s);
// 在链表s第一个节点前插入值为data的节点 
void SListPushFront(SList* s, SDataType data);
// 删除链表s的第一个节点 
void SListPopFront(SList* s);
// 在链表的pos位置后插入值为data的节点 
void SListInsert(PNode pos, SDataType data);
// 删除链表s中pos位置的节点 
void SListErase(SList* s, PNode*pos);
// 在链表中查找值为data的节点,找到返回该节点的地址,否则返回NULL 
PNode SListFind(SList* s, SDataType data);
// 获取链表中有效节点的个数 
size_t SListSize(SList* s);
// 检测链表是否为空 
int SListEmpty(SList* s);
// 将链表中有效节点清空 
void SListClear(SList* s);
// 销毁链表 
void SListDestroy(SList* s);

slist.c

#include "slist.h"
// 链表的初始化 

void SListInit(SList* s) {
	assert(s);
	s->_pHead = NULL;
}
PNode buyslistnode(SDataType data) {
	PNode newnode = (PNode)malloc(sizeof(Node));
	if (newnode == NULL) {
		return NULL;
	}
	newnode->_data = data;
	newnode->_pNext = NULL;
	return newnode;
}
// 在链表s最后一个节点后插入值为data的节点 
void SListPushBack(SList* s, SDataType data) {
	assert(s);
	PNode pnewnode = buyslistnode(data);
	if (s->_pHead == NULL) {
		s->_pHead = pnewnode;
	}
	else {
		PNode ps;
		ps = s->_pHead;
		while (ps->_pNext) {
			ps = ps->_pNext;
		}

		ps->_pNext = pnewnode;
	}
}
// 删除链表s最后一个节点 
void SListPopBack(SList* s) {
	assert(s);
	if (s->_pHead == NULL) {
		printf("链表为空\n");
	}
	else if (s->_pHead->_pNext == NULL) {//只有一个节点
		s->_pHead = NULL;
	}
	else {//多个节点
		PNode ps;
		ps = s->_pHead;
		while (ps->_pNext) {
			ps = ps->_pNext;
		}
		free(ps);
		ps = NULL;
	}
}
// 在链表s第一个节点前插入值为data的节点 
void SListPushFront(SList* s, SDataType data) {
	assert(s);
	PNode pnewnode = buyslistnode(data);
	pnewnode->_pNext = s->_pHead;
	s->_pHead = pnewnode;
	
}
// 删除链表s的第一个节点 
void SListPopFront(SList* s) {
	assert(s);
	if (s->_pHead == NULL) {
		printf("链表为空\n");
	}
	else {
		PNode pdhead=s->_pHead;
		s->_pHead = pdhead->_pNext;
		free(pdhead);
	}
}
// 在链表的pos位置后插入值为data的节点 
void SListInsert(PNode pos, SDataType data) {
	PNode pnewnode = buyslistnode(data);
	pnewnode->_pNext = pos->_pNext;
	pos->_pNext = pnewnode;
}
// 在链表中查找值为data的节点,找到返回该节点的地址,否则返回NULL 
PNode SListFind(SList* s, SDataType data) {
	assert(s);
	PNode ps3;
	ps3 = s->_pHead;
	if (ps3->_data == data) {//只有一个节点
		return ps3;
	}
	else {
		while (ps3->_pNext != NULL) {
			ps3 = ps3->_pNext;
			if (ps3->_data == data) {
				return ps3;
			}
		}
	}
	return NULL;
}
// 删除链表s中pos位置的节点 
void SListErase(SList* s,PNode pos){
	assert(s);
	if (pos == NULL) {
		printf("链表为空\n");
	}
	else if (pos == s->_pHead) {
		s->_pHead = s->_pHead->_pNext;
	}
	else {
		PNode pspre;
		pspre = s->_pHead;
		while (pspre->_pNext != pos) {
			pspre = pspre->_pNext;
		}
		pspre->_pNext = pos->_pNext;
	}
}
// 获取链表中有效节点的个数 
size_t SListSize(SList* s) {
	int count = 0;
	PNode pssize = s->_pHead;
	while (pssize) {
		pssize = pssize->_pNext;
		count++;
	}
	return count;
}
// 将链表中有效节点清空 
void SListClear(SList* s) {
	assert(s);
	s->_pHead = NULL;
}

test.c

#include "slist.h"
int main() {
	SList arr;
	PSList s = &arr;
	SListInit(s);
	SListPushBack(s, 1);
	SListPushFront(s, 2);
	SListPushBack(s, 1);
	SListPushBack(s, 3);
	SListPushBack(s, 1);
	SListPushBack(s, 1);
	SListInsert(SListFind(s, 3),5);
	SListErase(s, SListFind(s, 3));
	if (s->_pHead == NULL) {
		printf("链表为空\n");
	}
	else {
		printf("%d\n", s->_pHead->_data);
		PNode ps1 = s->_pHead;
		while (ps1->_pNext != NULL) {
			printf("%d\n", ps1->_pNext->_data);
			ps1 = ps1->_pNext;
		}
	}
	system("pause");
}

 

上一篇: 文件解析之CSV

下一篇: 22.括号生成