单链表:单向不带头结点非循环的链表
在实现过程中有以下几点需要注意:
1. 在需要改变头结点的指向时(如:尾插尾删头插头删销毁)我们需要用到二级指针,因为实参本身是地址,我们的形参要改变实参就要用二级指针,否则形参的改变不会影响外部的实参。
2. 在进行尾删时我们要考虑链表中只有一个节点的特殊情况。这时只需要改变头结点的指向即可。
3. 在进行任意位置删除和插入时,是在任意位置之后进行插入和删除操作,因为如果在任意位置之前我们需要先将任意位置之前的节点保存起来,在单链表中难以实现。
以下是我对其各个操作的实现:
头文件:
#pragma once
#include<stdio.h>
#include<Windows.h>
#include<assert.h>
#include<malloc.h>
#pragma warning(disable:4996)
typedef int DataType;
typedef struct SListNode{
DataType val;
struct SListNode *next;
}SListNode;
//尾插
void SListPushBack(SListNode **head,DataType val);
//尾删
void SListPopBack(SListNode **head);
//头插
void SListPushFront(SListNode **head,DataType val);
//头删
void SListPopFront(SListNode **head);
//打印单链表
void SListPrint(SListNode *head);
//获取元素个数
int SListSize(SListNode *head);
//在pos位置之后插入val
void SListInsert(SListNode *pos, DataType val);
//删除pos位置之后的val
void SListErase(SListNode *pos);
//销毁单链表
void SListDestroy(SListNode **head);
//查找
SListNode *SListFind(SListNode *head,int data);
void TestSList();
函数的实现:.c文件
#include"SList.h"
SListNode *BuyNewNode(DataType val)
{
SListNode *newnode = (SListNode*)malloc(sizeof(SListNode));
if (newnode == NULL){
assert(0);
}
newnode->val = val;
newnode->next = NULL;
return newnode;
}
//尾插
void SListPushBack(SListNode **head, DataType val)
{
assert(head);
SListNode *newnode = BuyNewNode(val);
if (NULL == *head){
*head = newnode;
}
else{
SListNode *cur = *head;
while (cur->next){
cur = cur->next;
}
cur->next = newnode;
}
}
//尾删
void SListPopBack(SListNode **head)
{
assert(head);
if (NULL == *head){
return;
}
else if ((*head)->next == NULL){
free(*head);
*head = NULL;
}
else{
SListNode *cur = *head;
SListNode *prev = NULL;
while (cur->next){
prev = cur;
cur = cur->next;
}
prev->next = cur->next;
free(cur);
}
}
//头插
void SListPushFront(SListNode **head, DataType val)
{
assert(head);
SListNode *newnode = BuyNewNode(val);
newnode->next = *head;
*head = newnode;
}
//头删
void SListPopFront(SListNode **head)
{
assert(head);
SListNode *delnode = NULL;
if (*head == NULL){
return;
}
else{
delnode = *head;
*head = delnode->next;
free(delnode);
}
}
//打印单链表
void SListPrint(SListNode *head)
{
assert(head);
SListNode *cur = head;
while (cur){
printf("%d->", cur->val);
cur = cur->next;
}
printf("NULL\n");
}
//获取元素个数
int SListSize(SListNode *head)
{
assert(head);
int count = 0;
SListNode *cur = head;
while (cur){
count++;
cur = cur->next;
}
return count;
}
//在pos位置之后插入val
void SListInsert(SListNode *pos, DataType val)
{
if (pos == NULL){
return;
}
SListNode *newnode = BuyNewNode(val);
newnode->next = pos->next;
pos->next = newnode;
}
//删除pos位置之后的val
void SListErase(SListNode *pos)
{
if (pos == NULL || pos->next == NULL){
return;
}
SListNode *delnode = pos->next;
pos->next = delnode->next;
free(delnode);
}
//销毁单链表
void SListDestroy(SListNode **head)
{
assert(head);
SListNode *cur = *head;
while (cur){
*head = cur->next;
free(cur);
cur = *head;
}
}
//查找
SListNode *SListFind(SListNode *head,int data)
{
assert(head);
SListNode *cur = head;
while (cur){
if (cur->val == data){
return cur;
}
cur = cur->next;
}
return NULL;
}
void TestSList()
{
SListNode *L = NULL;
SListPushBack(&L, 4);
SListPushBack(&L, 3);
SListPushBack(&L, 2);
SListPushBack(&L, 1);
SListPrint(L);
SListPushFront(&L, 5);
SListPushFront(&L, 6);
SListPushFront(&L, 7);
SListPrint(L);
printf("Size = %d\n", SListSize(L));
SListPopBack(&L);
SListPopFront(&L);
SListPrint(L);
SListInsert(SListFind(L, 6), 30);
SListPrint(L);
SListErase(SListFind(L, 6));
SListPrint(L);
SListDestroy(&L);
}
主函数测试
#include"SList.h"
int main()
{
TestSList();
system("pause");
return 0;
}
运行结果截图: