赞
踩
本博客将要实现的无头单向不循环链表。
我们将节点定义为如下结构:
其成员变量有data,next。
将int重命名为STLDataType,方便我们以后修改数据域的内容。
//无头单向不循环链表
typedef int SLTDataType;
typedef struct SListNode
{
SLTDataType data;
struct SListNode* next;
}SListNode;
动态申明一个空间,来放置数据。如下:
将data的内容置成形参x,next置NULL。
//申请一个节点
SListNode* BuySListNode(SLTDataType x)
{
SListNode* newnode = (SListNode*)malloc(sizeof(SListNode));
if (newnode == NULL)
{
perror("malloc");
exit(-1);
}
newnode->data = x;
newnode->next = NULL;
retur
循环遍历链表,直到尾节点。创建一个结构体指针变量cur,循环cur = cur->next,并打印cur->data的内容,直到cur == NULL。
//单链表打印
void SListPrint(SListNode* plist)
{
SListNode* cur = plist;
while (cur != NULL)
{
printf("%d->", cur->data);
cur = cur->next;
}
printf("NULL\n");
}
当链表为NULL,我们就要修改头结点本身的内容,所以我们需要头结点的指针,而本文中头结点本身就是结构体指针,所以尾插函数参数我们需要二级指针。
//单链表尾插 void SListPushBack(SListNode** pplist, SLTDataType x) { assert(pplist); SListNode* newnode = BuySListNode(x); if (*pplist != NULL) { SListNode* cur = *pplist; while (cur->next != NULL) { cur = cur->next; } cur->next = newnode; } else { *pplist = newnode; } }
对于头插而言,链表是否有元素并不重要,我们只需要让新节点的指向头结点,并将头结点等于新节点。
因为头插链表,一定会改变头结点的内容,所以我们头插函数的形参也是二级指针。
//单链表的头插
void SListPushFront(SListNode** pplist, SLTDataType x)
{
assert(pplist);
SListNode* newnode = BuySListNode(x);
newnode->next = *pplist;
*pplist = newnode;
}
当链表元素只有一个时,此时尾删链表,要修改头结点的内容,尾删函数的形参需要二级指针。
//单链表的尾删 void SListPopBack(SListNode** pplist) { assert(pplist); //链表为NULL assert(*pplist); if ((*pplist)->next == NULL) { free(*pplist); *pplist = NULL; } else { SListNode* cur = *pplist; SListNode* prev = NULL; while (cur->next != NULL) { prev = cur; cur = cur->next; } prev->next = NULL; free(cur); } }
我们需要一个结构体指针变量next,来保存头结点的下一个节点,然后free头结点,使头结点 = 指针变量next。
//单链表头删
void SListPopFront(SListNode** pplist)
{
assert(pplist);
assert(*pplist);
SListNode* next = (*pplist)->next;
free(*pplist);
*pplist = next;
}
我们需要一个结构体指针变量cur,来遍历链表比较cur->data == x,如果相等,放回此时cur的内容(该节点的地址)。如果遍历完链表,并没有相等元素,放回NULL。
//单链表的查找
SListNode* SListFind(SListNode* plist, SLTDataType x)
{
SListNode* cur = plist;
while (cur != NULL)
{
if (cur->data == x)
{
return cur;
}
cur = cur->next;
}
return NULL;
}
我们让newnode指向pos下一个的节点,pos指向newnode。
//单链表在pos位置之后插入x
void SListInsertAfter(SListNode* pos, SLTDataType x)
{
assert(pos);
SListNode* newnode = BuySListNode(x);
newnode->next = pos->next;
pos->next = newnode;
}
我们需要一个结构体指针变量next,记录pos下一个节点的地址,然后是pos指向next的下一个节点,接着free(next)。
//单链表删除在pos位置之后的值
void SListEraseAfter(SListNode* pos)
{
assert(pos && pos->next);
SListNode* next = pos->next;
pos->next = next->next;
free(next);
}
我们需要两个结构体指针prev,cur。先让prev = cur ,cur再指向下一个节点,free(prev),重复上述操作,直到cur指向NULL。
需要我们在函数调用完后,自己对头结点置NULL。
//单链表的销毁
void SListDestroy(SListNode* plist)
{
assert(plist);
SListNode* cur = plist;
while (cur != NULL)
{
SListNode* prev = cur;
cur = cur->next;
free(prev);
}
}
//slist.h 文件 #pragma once #define _CRT_SECURE_NO_WARNINGS 1 #include <stdio.h> #include <stdlib.h> #include <assert.h> //无头单向不循环链表 typedef int SLTDataType; typedef struct SListNode { SLTDataType data; struct SListNode* next; }SListNode; //申请一个节点 SListNode* BuySListNode(SLTDataType x); //单链表打印 void SListPrint(SListNode* plist); //单链表尾插 void SListPushBack(SListNode** pplist, SLTDataType x); //单链表的头插 void SListPushFront(SListNode** pplist, SLTDataType x); //单链表的尾删 void SListPopBack(SListNode** pplist); //单链表头删 void SListPopFront(SListNode** pplist); //单链表的查找 SListNode* SListFind(SListNode* plist, SLTDataType x); //单链表在pos位置之后插入x void SListInsertAfter(SListNode* pos, SLTDataType x); //单链表删除在pos位置之后的值 void SListEraseAfter(SListNode* pos); //单链表的销毁 void SListDestroy(SListNode* plist);
//slist.c 文件 #include "slist.h" //申请一个节点 SListNode* BuySListNode(SLTDataType x) { SListNode* newnode = (SListNode*)malloc(sizeof(SListNode)); if (newnode == NULL) { perror("malloc"); exit(-1); } newnode->data = x; newnode->next = NULL; return newnode; } //单链表打印 void SListPrint(SListNode* plist) { SListNode* cur = plist; while (cur != NULL) { printf("%d->", cur->data); cur = cur->next; } printf("NULL\n"); } //单链表尾插 void SListPushBack(SListNode** pplist, SLTDataType x) { assert(pplist); SListNode* newnode = BuySListNode(x); if (*pplist != NULL) { SListNode* cur = *pplist; while (cur->next != NULL) { cur = cur->next; } cur->next = newnode; } else { *pplist = newnode; } } //单链表的头插 void SListPushFront(SListNode** pplist, SLTDataType x) { assert(pplist); SListNode* newnode = BuySListNode(x); newnode->next = *pplist; *pplist = newnode; } //单链表的尾删 void SListPopBack(SListNode** pplist) { assert(pplist); //链表为NULL assert(*pplist); if ((*pplist)->next == NULL) { free(*pplist); *pplist = NULL; } else { SListNode* cur = *pplist; SListNode* prev = NULL; while (cur->next != NULL) { prev = cur; cur = cur->next; } prev->next = NULL; free(cur); } } //单链表头删 void SListPopFront(SListNode** pplist) { assert(pplist); assert(*pplist); SListNode* next = (*pplist)->next; free(*pplist); *pplist = next; } //单链表的查找 SListNode* SListFind(SListNode* plist, SLTDataType x) { SListNode* cur = plist; while (cur != NULL) { if (cur->data == x) { return cur; } cur = cur->next; } return NULL; } //单链表在pos位置之后插入x void SListInsertAfter(SListNode* pos, SLTDataType x) { assert(pos); SListNode* newnode = BuySListNode(x); newnode->next = pos->next; pos->next = newnode; } //单链表删除在pos位置之后的值 void SListEraseAfter(SListNode* pos) { assert(pos && pos->next); SListNode* next = pos->next; pos->next = next->next; free(next); } //单链表的销毁 void SListDestroy(SListNode* plist) { assert(plist); SListNode* cur = plist; while (cur != NULL) { SListNode* prev = cur; cur = cur->next; free(prev); } }
以上就是我对于无头单向不循环链表的实现!!!
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。