数据结构2--不带头结点的单链表

不带头结点的单链表

按值删除注意考虑第一个节点,按值插入注意考虑没有元素时

排序时用四个指针: tmp是在排序好的列表里寻找要插入的位置、prev标记tmp的前一个节点、p标记要插入的节点、q标记要插入的节点的下一个节点,每次插入完成之后,都需要将tmp置到第一个结点的位置,prev置空

//Common.h
#ifndef _COMMON_H_
#define _COMMON_H_

#include <stdio.h>
#include <stdlib.h>
#include <assert.h>
#include <vld.h>
#include <memory.h>
#include <stdbool.h>
typedef int ElemType;

#endif 
//main.cpp
#include "slist.h"

int main()
{
	SList list;//单链表 SListNode* list
	SListInit(&list);
    system("pause");
    return 0;
}
//slist。h
#ifndef _SLIST_H_
#define _SLIST_H_

#include "Common.h"
typedef struct SListNode
{
	ElemType data;
	struct SListNode* next;
}SListNode;

//不带头结点的单链表
typedef SListNode* SList;

void SListInit(SList* phead);
void SListPushBack(SList* phead,ElemType x);
void SListPopBack(SList* phead);
void SListPushFront(SList* phead,ElemType x);
void SListPopFront(SList* phead);

void SListShow(SList phead);
size_t SListLength(SList phead);
SListNode* SListFind(SList phead,ElemType key);

void SListEraseyVal(SList* phead,ElemType key);
void SListInsertByVal(SList* phead,ElemType key);
void SListSort(SList* phead);
ElemType SListFront(SList phead);
ElemType SListBack(SList phead);
void SListReverse(SList* phead);
void SListClear(SList* phead);
void SListDestory(SList* phead);


void SListInit(SList* phead)
{
	assert(phead != NULL);
	*phead = NULL;
}
void SListPushBack(SList* phead, ElemType x)
{
	assert(phead != NULL);
	//申请空间放节点
	SListNode* s = (SListNode*)malloc(sizeof(SListNode));
	s->data = x;
	s->next = NULL;

	
	if (p == NULL)
	{
		*phead = s;
	}
	else{
		while (p->next != NULL)
		{
			p = p->next;
		}
		p->next = s;
	}
}
void SListPopBack(SList* phead)
{
	assert(phead != NULL);
	if (*phead == NULL)
	{
		printf("链表为空,不能进行删除!\n");
	}
	//找尾部
	SListNode* p = *phead;
	SListNode* prev = NULL;
	while (p->next != NULL)
	{
		prev = p;
		p = p->next;
	}
	//!!!注意:考虑链表中是否只有一个节点
	if (prev == NULL)
	{
		*phead = NULL;
	}
	else{
		prev->next = NULL;
	}
	free(p);
}
void SListPushFront(SList* phead,ElemType x)
{
	assert(phead != NULL);
	
	//先开辟空间放节点
	SListNode* s = (SListNode*)malloc(sizeof(SListNode));
	assert(s != NULL);
	s->data = x;
	s->next = NULL;
	
	//将其链接进去 没有元素的情况也适用
	s->next = *phead;
	*phead = s;
	
}
void SListPopFront(SList* phead)
{
	assert(phead != NULL);
	SListNode* p = *phead;
	if (p == NULL)
	{
		printf("链表中没有元素,不能进行头删!\n");
	}


	//只有一个元素或者正常的情况都可适用
	else{
		*phead = p->next;
		free(p);
	}
}
void SListShow(SList phead)
{
	assert(phead != NULL);
	SListNode* p = phead;
	while (p != NULL)
	{
		printf("%d->", p->data);
		p = p->next;
	}
	printf("over\n");
}
size_t SListLength(SList phead)
{
	assert(phead != NULL);
	SListNode* p = phead;
	size_t length= 0;
	while (p != NULL)
	{
		length++;
		p = p->next;
	}
	return length;
}
SListNode* SListFind(SList phead, ElemType key)
{
	assert(phead != NULL);
	SListNode*p = phead;
	while (p != NULL&&p->data != key)
	{
		p = p->next;
	}
	//走到这里 如果没找到的话p是空的 找到的话p是有值的
	return p;

}
//!!!注意 注意考虑第一个节点
void SListEraseyVal(SList* phead, ElemType key)
{
	assert(phead != NULL);
	//找数据是否存在
	SListNode* p=SListFind(*phead, key);
	if (p == NULL)
		return;

	while (prev != p&&prev->next != p)
	{
		prev = prev->next;
	}
	if (prev == p)
	{
		*phead = p->next;
	}
	else{
		prev->next = p->next;
	}
	free(p);
	//自己写的
	/*SListNode* prev = NULL;
	SListNode* q = *phead;
	while (q != p)
	{
		prev = q;
		q = q->next;
	}
	prev->next = q->next;
	free(q);
	free(p);*/
}


void SListInsertByVal(SList* phead, ElemType key)
{
	assert(phead != NULL);
	//先申请节点
	SListNode* s = (SListNode*)malloc(sizeof(SListNode));
	assert(s != NULL);
	s->data = key;
	s->next = NULL;

	//链接起来
	SListNode* p = *phead;
	SListNode* prev = NULL;
	 
	//包含最后一个元素 注意可以往最后一个元素的后面插入
	while (p!= NULL&&p->data < key)
	{
		
			//找到插入的位置
			prev = p;
			p = p->next;
		
	}
	//考虑特殊情况
	//说明没有元素
	if (prev == NULL)
	{
		s->next = *phead;
		*phead = s;
	}
	else
	{
		s->next = prev->next;
		prev->next = s;
	}
}
void SListSort(SList* phead)
{
	assert(phead != NULL);
	if (SListLength(*phead) <= 1)
	{
		return;
	}

	SListNode* tmp=*phead, *prev=NULL;
	SListNode* p = *phead;
	SListNode* q = p->next;
	//断开连接
	p->next = NULL;

	while (q != NULL)
	{
		p = q;
		q = q->next; 
		//寻找插入位置 tmp为空时说明遍历完成
		while (tmp->data < p->data&&tmp != NULL)
		{
			prev = tmp;
			tmp = tmp->next;
		}
		if (prev == NULL)
		{
			p->next == *phead;
			*phead = p;
		}
		else
		{
			p->next = prev->next;
			prev->next = p;
		}
		tmp = *phead;
		prev = NULL;
	}

}
ElemType SListFront(SList phead)
{
	assert(phead != NULL);
	return phead->data;
}
ElemType SListBack(SList phead)
{
	assert(phead != NULL);
	SListNode* p = phead;
	while (p->next != NULL)
	{
		p = p->next;
	}
	return p->data;
}
void SListReverse(SList* phead)
{
	assert(phead != NULL);
	SListNode *p = *phead;
	SListNode *q = p->next;
	p->next = NULL;

	while (q != NULL)
	{
		p = q;
		q = q->next;
		p->next = *phead;
		*phead = p;
	}
}
void SListClear(SList* phead)
{
	assert(phead != NULL);
	SListNode* p = NULL;
	while (*phead != NULL)
	{
		p = *phead;
		*phead = p->next;
			free(p);
	}
}
void SListDestory(SList* phead)
{
	SListClear(phead);
}
#endif

猜你喜欢

转载自blog.csdn.net/weixin_43807876/article/details/115250777