不带头结点的单链表
按值删除注意考虑第一个节点,按值插入注意考虑没有元素时
排序时用四个指针: 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