无头单向非循环链表基本操作实现

之前写了动态顺序表的实现,但动态顺序表还是存在以下问题

  1. 中间/头部的插入删除,时间复杂度为O(N)
  2. 增容需要申请新空间,拷贝数据,释放旧空间。会有不小的消耗。
  3. 增容一般是呈2倍的增长,势必会有一定的空间浪费。例如当前容量为100,满了以后增容到200,
    我们再继续插入了5个数据,后面没有数据插入了,那么就浪费了95个数据空间。
    所以我们有引入一种新的数据结构链表来解决顺序表所存在的问题
    ** SList.h**
#ifndef __SLIST_H__
#define __SLIST_H__

#include<stdio.h>
#include<stdlib.h>
#include<assert.h>
#include<malloc.h>

typedef int SLDataType;

typedef struct SListNode
{
	SLDataType _a;
	struct SListNode* _next;
}SListNode;

typedef struct SList
{
	SListNode* _head;
}SList;

void SListInit(SList* psl);
void SListDestory(SList* psl);

void SListPushBack(SList* psl, SLDataType x);
void SListPopBack(SList* psl);
void SListPushFront(SList* psl, SLDataType x);
void SListPopFront(SList* psl);

SListNode* SListFind(SList* psl, SLDataType x);
void SListInsertAfter(SListNode* pos, SLDataType x);//在指定位置后面插入
void SListEraseAfter(SListNode* pos);
void SListRemove(SList* psl, SLDataType x);
void SListPrint(SList* psl);
void Test();
#endif //__SLIST_H__

//单链表的头删和尾删都要对只有一个节点进行判断。
//单链表的头插入和尾插入,也要对只有一个节点进行处理;

** SList.h**

#include "SList.h"

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

void SListDestory(SList* psl)
{
	SListNode* cur = psl->_head;
	SListNode* next = NULL;
	assert(psl);
	while(cur != NULL)
	{
		next = cur->_next;
		free(cur);
		cur = NULL;
		cur = next;
	}
	psl->_head = NULL;
}

SListNode* SListBuyNode(SLDataType x)
{
	SListNode* newnode = (SListNode*)malloc(sizeof(SListNode));
	newnode->_a = x;
	newnode->_next = NULL;
	return newnode;
}

void SListPushBack(SList* psl, SLDataType x)
{
	SListNode* cur = psl->_head;
	assert(psl);
	if(psl->_head == NULL)
	{
		psl->_head = SListBuyNode(x);
	}
	else
	{
		while(cur->_next != NULL)
		{
			cur = cur->_next;
		}
		cur->_next = SListBuyNode(x);
	}
}

void SListPopBack(SList* psl)
{
	SListNode* prev = NULL;
	SListNode* cur = psl->_head;
	assert(psl);
	//对只有一个节点特殊处理
	if(cur->_next == NULL)
	{
		free(cur);
		cur = NULL;
		psl->_head = NULL;	
	}
	else
	{
		//单链表找尾,用指针的next判断
		while(cur->_next != NULL)
	{
		prev = cur;
		cur = cur->_next;
	}
		free(cur);
		cur = NULL;
		prev->_next = NULL;
	}
}

void SListPushFront(SList* psl, SLDataType x)
{
	SListNode* node = NULL;
	assert(psl);
	if(psl->_head == NULL)
	{
		psl->_head = SListBuyNode(x);
	}
	else
	{
		node = SListBuyNode(x);
		node->_next = psl->_head;
		psl->_head = node;
	}
}

void SListPopFront(SList* psl)
{
	SListNode* del = psl->_head;
	assert(psl);
	if(del->_next == NULL)
	{
		free(del);
		del = NULL;
		psl->_head = NULL;
	}
	else
	{
		psl->_head = del->_next;
		free(del);
		del = NULL;
	}

}


void SListPrint(SList* psl)
{
	 SListNode* cur = psl->_head;
	 assert(psl);
	 while(cur != NULL)
	 {
		 printf("%d ", cur->_a);
		 cur = cur->_next;
	 }
	 printf("\n");
}

void SListInsertAfter(SListNode* pos, SLDataType x)
{
	SListNode* next = pos->_next;
	SListNode* node = NULL;
	assert(pos);
	node = SListBuyNode(x);
	pos->_next = node;
	node = next;
}

void SListEraseAfter(SListNode* pos)
{
	SListNode* del = pos->_next;
	SListNode* next = del->_next;
	pos->_next = next;
	free(del);
	del = NULL;
}
SListNode* SListFind(SList* psl, SLDataType x)
{
	SListNode* cur = psl->_head;
	assert(psl);
	while(cur != NULL)
	{
		if(cur->_a == x)
		{
			return cur;
		}
		else
		{
			cur = cur->_next;
		}
	}
	return NULL;
}

void SListRemove(SList* psl, SLDataType x)
{
	SListNode* prev = NULL;
	SListNode* pos = psl->_head;
	assert(psl);
	while(pos != NULL)
	{
		prev = pos;
		if(pos->_a == x)
		{
			break;
		}
		else
		{
			pos = pos->_next;
		}
	}
	if(pos == NULL)
	{
		;
	}
	else
	{
		prev->_next = pos->_next;
		free(pos);
		pos = NULL;
	}
}
void Test()
{
	SList s;
	SListInit(&s);
	SListPushBack(&s, 1);
	SListPushBack(&s, 2);
	SListPushBack(&s, 3);
	SListPushBack(&s, 4);
	SListPrint(&s);

	//SListPopBack(&s);
	//SListPopBack(&s);
	//SListPopBack(&s);
	//SListPopBack(&s);

	SListPushFront(&s, 10);
	/*SListPopBack(&s);
	SListPopFront(&s);
	SListPopFront(&s);
	SListPopFront(&s);*/

	SListPrint(&s);
}

猜你喜欢

转载自blog.csdn.net/aixintianshideshouhu/article/details/83009621