无头单链表的操作
△节点结构
typedef定义
{
1.结点元素
2.Next的指针
}
//不带头节点的单链表
typedef int SDataType;
// 节点结构
typedef struct SListNode
{
SDataType _data;
struct SListNode* _pNext;
}Node,*pNode;
△链表结构
typedef定义
{
头指针
}
// 给一个链表结构
typedef struct SList
{
Node* _pHead;
}SList;
△链表的初始化
1.断言
2.头指针指向NULL
// 链表的初始化
void SListInit(SList* pl)
{
assert(pl);
pl->_pHead = NULL;
}
△创建新结点
1.为新结点申请动态内存空间
2.判断新结点是否为空
3.将元素的值赋给新结点
4.将新结点的Next域指向NULL
//创建一个结点
pNode BuyListNode(SDataType data)
{
pNode pNewNode = (Node*)malloc(sizeof(Node));
if (pNewNode == NULL)
{
assert(0);
return NULL;
}
pNewNode->_data = data;
pNewNode->_pNext = NULL;
}
△尾插法
0.断言assert( )
1.链表为空
让头指针指向新结点
2.只有一个结点
让头指针的Next指向新结点
3.有多个结点
遍历,找到链表中Next域为空的结点,将该结点的Next指向新结点
void SListPushBack(SList* pl, SDataType data)
{
//1.链表为空
if (pl->_pHead == NULL)
{
pl->_pHead = BuyListNode(data);
}
//2.只有一个结点
else if (pl->_pHead->_pNext == NULL)
{
pl->_pHead->_pNext = BuyListNode(data);
}
//3.有多个结点
else
{
pNode cur = pl->_pHead;
while (cur->_pNext!=NULL)
{
cur = cur->_pNext;
}
cur->_pNext = BuyListNode(data);
}
}
△尾删法
1.断言assert
2.链表为空
返回;
3.只有一个结点
free掉头指针的Next域;
让头指针指向NULL;
4.有多个结点
设置指针cur,保存链表的最后一个结点;
设置指针pre,保存链表的倒数第二个结点;
让cur指向头指针,将指针pre置为空,然后让cur从链表第一个元素向后遍历,pre指向cur,当cur指向的结点的Next域为NULL时,遍历结束,此时,cur指向链表的最后一个结点,pre指向了链表的倒数第二个结点,free掉cur,将pre的Next域指向空。
// 尾删法
void SListPopBack(SList* pl)
{
assert(pl);
if (NULL == pl->_pHead)
{
printf("链表为空!");
return NULL;
}
//只有一个结点
else if (pl->_pHead->_pNext==NULL)
{
free(pl->_pHead->_pNext);
pl->_pHead = NULL;
}
//有多个结点
else
{
pNode cur = pl->_pHead;
pNode pre = NULL;
while (cur->_pNext)
{
pre = cur;
cur = cur->_pNext;
}
free(cur);
cur = NULL;
pre->_pNext = NULL;
}
}
△头插法
1.判表空
2.设置一个cur指针存放新结点
3.将cur指向头指针的Next域,将头指针指向cur
void SListPushFront(SList* pl, SDataType data)
{
assert(pl);
if (pl->_pHead == NULL)
{
pl->_pHead= BuyListNode(data);
}
else
{
pNode cur = BuyListNode(data);
cur->_pNext = pl->_pHead;
pl->_pHead = cur;
}
}
△头删法
1.判表空
2.只有一个结点:
将头指针指向NULL
3.有多个结点:
设置一个指针cur指向头指针的Next域,将头指针指向cur的Next域,free掉cur
void SListPopFront(SList* pl)
{
assert(pl);
if (pl->_pHead == NULL)
{
printf("链表为空!");
return NULL;
}
else if (pl->_pHead->_pNext==NULL)
{
pl->_pHead = NULL;
}
else
{
pNode cur = pl->_pHead;
pl->_pHead = cur->_pNext;
free(cur);
}
}
△在链表pos位置后插入置为data的节点
1.判断插入位置是否合法
2.设置两个指针cur,pre,cru指针指向头指针,pre指针指向NULL,若cur不等于pos,cur继续往后走,若cur等于pos,将data存放在pre中,将Pre指向cur的Next域,将cur的Next域指向pre。