c语言实现单链表
用C语言实现链表的头插,头删,尾插,尾删,查找节点,任意节点插入,和任意节点删除等功能
此代码运用的是二级指针实现单链表,所以在写代码时要注意参数类型。
关于二级指针和一级指针:
一级指针变量指向的内容是普通变量的值,二级指针变量指向的内容是一级指针变量的地址。
当你想对一个地址做修改的时候,就要用到二级指针。
完整代码
#define __CRT_SECURE_NO_WARNRINGS 1
#include "slist.h"
//初始化链表
void InitLinkList(ListNode** ppList){
assert(ppList);
*ppList = NULL;
}
//打印链表
void PrintList(ListNode* pList){
ListNode* cur = pList;
while (cur){
printf("%d ", cur->data);
cur= cur->next;
}
printf("\n");
return;
}
//申请一个新节点
ListNode* Buynewnode(DataType x){
ListNode* newNode = NULL;
newNode = (ListNode*)malloc(sizeof(ListNode));//开辟新节点,强制类型转换
if (newNode == NULL){
printf("out of memory \n");//溢出
}
else{
newNode->data = x;
newNode->next = NULL;
}
return newNode;
}
//尾插
void PushBack(ListNode** ppList, DataType x){
assert(ppList);
if (*ppList == NULL){
*ppList = Buynewnode(x);
}
else{
ListNode* ppcur = NULL;
ppcur = *ppList;
while (ppcur->next)
{
ppcur = ppcur->next;
}
ppcur->next = Buynewnode(x);
}
}
//尾删
void PopBack(ListNode** ppList){
assert(ppList);
ListNode* cur = *ppList;
if (cur == NULL){
return ;
}
if (cur->next==NULL){
free(cur);
cur = NULL;
}
else{
while (cur->next->next){
cur = cur->next;
}
free(cur->next);
cur->next = NULL;
}
}
//头插
void PushFront(ListNode** ppList, DataType x){
assert(ppList);
ListNode* pFirst=NULL;
if (*ppList==NULL){
*ppList = Buynewnode(x);
}
else{
pFirst = Buynewnode(x);
pFirst->next = *ppList;
*ppList = pFirst;
}
}
//头删
void PopFront(ListNode** ppList){
assert(ppList);
if (*ppList == NULL){
return;
}
else{
ListNode* cur = *ppList;
*ppList = (*ppList)->next;
free(cur);
cur = NULL;
}
}
//查找表中元素x
ListNode* Find(ListNode* pList, DataType x){
assert(pList);
ListNode* cur = pList;
//if (cur == NULL){
// return ;
//}
while (cur){
if (cur->data == x)
break;
cur = cur->next;
}
return cur;
}
// 在pos的前面插入一个节点x
void Insert(ListNode** ppList, ListNode* pos, DataType x){
assert(ppList);
assert(pos);
DataType tmp=0;
ListNode* newnode = Buynewnode(x);
if (*ppList == NULL){
PushBack(ppList, x);
}
else if (pos == NULL){
return;
}
else{
newnode->next =pos->next;
pos->next = newnode;
tmp = pos->data;
pos->data = newnode->data;
newnode->data = tmp;
}
}
//删除pos前一位置节点
void Erase(ListNode** ppList, ListNode* pos){
assert(ppList);
assert(pos);
ListNode* cur = *ppList;
if (cur == NULL){
return;
}
else{
while (cur->next!=pos&&cur){
cur = cur->next;
}
cur->next = pos->next;
free(pos);
pos = NULL;
}
}
测试函数
#include "slist.h"
//测试
void test1()
{
ListNode *list;
InitLinkList(&list);
printf("插入数据\n");
PushBack(&list, 1);
PushBack(&list, 2);
PushBack(&list, 3);
PushBack(&list, 4);
PushBack(&list, 5);
PushBack(&list, 6);
PrintList(list);
printf("从尾部删除数据后\n");
PopBack(&list);
PopBack(&list);
PrintList(list);
ListNode* _find;
_find=Find(list, 2);
printf("找到节点pos:%d\n", _find->data);
ListNode* pos = _find;
printf("在pos前插入节点:\n");
Insert(&list,pos, 7);
PrintList(list);
printf("删除pos前节点:\n");
Erase(&list, pos);
PrintList(list);
}
void test2()
{
ListNode* List;
InitLinkList(&List);
printf("头插数据\n");
PushFront(&List, 1);
PushFront(&List, 2);
PushFront(&List, 3);
PushFront(&List, 4);
PrintList(List);
printf("头删数据后");
PopFront(&List);
PopFront(&List);
PopFront(&List);
PopFront(&List);
PrintList(List);
}
int main()
{
test1();
//test2();
system("pause");
return 0;
}
头文件
#define __CRT_SECURE_NO_WARNRINGS 1
#ifndef __SLIST_H__
#define __SLIST_H__
#include <stdio.h>
#include <stdlib.h>
#include <assert.h>
typedef int DataType;
typedef struct ListNode
{
DataType data;
struct ListNode* next;
}ListNode;
void InitLinkList(ListNode** ppList);
void PrintList(ListNode* pList);
ListNode* Buynewnode(DataType x);
void PushBack(ListNode** ppList, DataType x);
void PopBack(ListNode** ppList);
void PushFront(ListNode** ppList, DataType x);
void PopFront(ListNode** ppList);
ListNode* Find(ListNode* pList, DataType x);
// 在pos的前面插入一个节点x
void Insert(ListNode** ppList, ListNode* pos, DataType x);
void Erase(ListNode** ppList, ListNode* pos);
#endif //__SLIST_H__
测试结果:
test1:
test2: