【C语言】链表总结+部分算法

前言:

从最开始的连链表都建立不来到现在自己补充函数
我从csdn的复制(原作者)到现在自己讲出理解。

这篇文章我着重讲一讲意义与运用
我的博客

基础:

#include <stdio.h>

#include <assert.h>

#include <stdlib.h>

#include <string.h>
typedef struct SListNode
typedef int SDataType;
//链表的节点

SDataType _data;
struct SListNode* _PNext;
}Node, * PNode;//创建结构体

typedef struct SList
{
    
    
PNode _pHead;
}SList;//指向链表第一个节点

struct SListNode* BuySListNode(SDataType data) {
    
    
struct SListNode* p;
p = (SListNode*)malloc(sizeof(struct SListNode));
p->_data = data;
p->_PNext = NULL;
return p;
}//创造新指针

void SListInit(SList* s) {
    
    
assert(s);
s->_pHead = NULL;
}//链表初始化

int SListEmpty(SList* s) {
    
    
assert(s);
if (s->_pHead == NULL) {
    
    
return -1;
}
return 0;
}//检测链表是否为空

void SListClear(SList* s) {
    
    
assert(s);
if (s->_pHead == NULL) {
    
    
return;
}
PNode pCur = s->_pHead;
while (pCur->_PNext) {
    
     //循环清空链表中的节点
PNode Tmp = pCur->_PNext;
free(pCur);
pCur = Tmp;
}
if (pCur) {
    
     //清空最后一个节点
free(pCur);
pCur = NULL;
}
}//清空链表

void SListDestroy(SList* s) {
    
    
assert(s);
if (s->_pHead == NULL) {
    
    
free(s->_pHead);
return;
}
while (s->_pHead) {
    
    
PNode Tmp = s->_pHead->_PNext;
free(s->_pHead);
s->_pHead = Tmp;
}
}//销毁链表

void SListPrint(SList* s) {
    
    
assert(s);
PNode pCur = s->_pHead;
while (pCur) {
    
    
printf("%d--->", pCur->_data);
pCur = pCur->_PNext;
}
printf("\n");
}//打印链表

int SListSize(SList* s) {
    
    
assert(s);
int count = 0;
PNode pCur = s->_pHead;
while (pCur) {
    
    
count++;
pCur = pCur->_PNext;
}
return count;
}//获取链表有效节点的个数

void SListPrint2(struct SListNode* head) {
    
    
while (head) {
    
    
printf("%d--->", head->_data);
head = head->_PNext;
}
}//针对首指针的头指针输出

void SListPrintNode(SListNode* f) {
    
    
printf("%d", f->_data);
printf("\n");
}//对某个节点的值输出

功能

void SListPushBack(SList* s, SDataType data) {
    
    
//找链表最后一个节点
assert(s);
PNode pNewNode = BuySListNode(data);
if (s->_pHead == NULL) {
    
    //链表没有节点的情况
s->_pHead = pNewNode;
}
else {
    
    
PNode pCur = s->_pHead;
while (pCur->_PNext) {
    
    
pCur = pCur->_PNext;
}
//让最后一个节点指向新节点
pCur->_PNext = pNewNode;
}
}//尾插

void SListPopBack(SList* s) {
    
    
assert(s);
if (s->_pHead == NULL) {
    
    //链表中没有节点
return;
}
else if (s->_pHead->_PNext == NULL) {
    
    //只有一个节点
free(s->_pHead);
s->_pHead = NULL;
}
else {
    
     //多个节点
PNode pCur = s->_pHead;
PNode pPre = NULL;
while (pCur->_PNext) {
    
    
pPre = pCur;
pCur = pCur->_PNext;
}
free(pCur);
pPre->_PNext = NULL;
}
}//尾删

void SListPushFront(SList* s, SDataType data) {
    
    
assert(s);
PNode pNewNode = BuySListNode(data);
if (s->_pHead == NULL) {
    
    //链表为空
s->_pHead = pNewNode;
}
else {
    
    
pNewNode->_PNext = s->_pHead;
s->_pHead = pNewNode;
}
}//头插

void SListPopFront(SList* s) {
    
    
assert(s);
if (s->_pHead == NULL) {
    
    //链表为空
return;
}
else if (s->_pHead->_PNext == NULL) {
    
    //只有一个节点
free(s->_pHead);
s->_pHead = NULL;
}
else {
    
    
PNode pCur = s->_pHead;
s->_pHead = pCur->_PNext;
free(pCur);
}
}//头删

void SListInsert(PNode pos, SDataType data) {
    
    
PNode pNewNode = NULL;
if (pos == NULL) {
    
    
return;
}
pNewNode = BuySListNode(data);

pNewNode->_PNext = pos->_PNext;
pos->_PNext = pNewNode;
}//插入

PNode SListFind(SList* s, SDataType data) {
    
    
assert(s);
PNode pCur = s->_pHead;
while (pCur) {
    
    
if (pCur->_data == data) {
    
    
return pCur;
}
pCur = pCur->_PNext;
}
return NULL;
}//查找

void SListErase(SList* s, PNode pos) {
    
    
assert(s);
if (pos == NULL || s->_pHead == NULL) {
    
    
return;
}
if (pos == s->_pHead) {
    
    
s->_pHead = pos->_PNext;
}
else {
    
    
PNode pPrePos = s->_pHead;
while (pPrePos && pPrePos->_PNext != pos) {
    
    
pPrePos = pPrePos->_PNext;
}
pPrePos->_PNext = pos->_PNext;
}
free(pos);
}//删除给定pos位置的节点。

void SListRemove(SList* s, SDataType data) {
    
    
assert(s);
if (s->_pHead == NULL) {
    
    
return;
}
PNode pPre = NULL;
PNode pCur = s->_pHead;
while (pCur) {
    
    
if (pCur->_data == data) {
    
    
if (pCur == s->_pHead) {
    
     //要删除的是第一个位置的节点
s->_pHead = pCur->_PNext;
}
else {
    
    
pPre->_PNext = pCur->_PNext; //其它位置的情况,让前一个节点指向其后一个节点
}
free(pCur);
return;
}
else {
    
    
pPre = pCur;
pCur = pCur->_PNext;
}
}
}//删除第一个值为data的节点

void Makecircle(SList* s){
    
    
assert(s);
PNode pCur = s->_pHead;
while (pCur->_PNext) {
    
    
pCur = pCur->_PNext;
}
pCur->_PNext = s->_pHead;
}//造圆

void Merge(SList* p, SList* s) {
    
    
assert(p);
assert(s);
PNode pCur = p->_pHead;
while (pCur->_PNext) {
    
    
pCur = pCur->_PNext;
}
pCur->_PNext = s->_pHead;
}//合并

进阶算法

struct SListNode* swapPairs(struct SListNode *_pHead) {
    
    
if (_pHead == NULL || _pHead->_PNext == NULL) return _pHead;
struct SListNode* nex = _pHead->_PNext;
_pHead->_PNext = swapPairs(nex->_PNext);//递归完head->next->next之后所有节点交换完毕
nex->_PNext = _pHead;
return nex;
}//两两交换链表中的节点

struct SListNode* getIntersectionNode(SListNode* _PaNext) {
    
    
SListNode* head = _PaNext;//头部
SListNode* f = _PaNext;
SListNode* s = _PaNext;//快慢指针指向头部
do {
    
    
f = f->_PNext->_PNext;
s = s->_PNext;
if (f == NULL) {
    
    
return NULL;//无环
}
} while (f!=s);
f = head;
while (f != s) {
    
    
f = f->_PNext;
s = s->_PNext;
}
return s;
}//找循环链表与单链表交点

struct SListNode*getIntersectionNode(SListNode* _PaNext,SListNode* _PbNext){
    
    
int count1=0,count2=0;
SListNode ret={
    
    0;NULL}
SListNode* p = _PaNext;
SListNode* q = _PbNext;//双指针
SListNode* headA=_PaNext;
SListNode* headB=_PbNext;//指路到头节点
while(p!=NULL){
    
    
p=p._PNext;
++count1;
}
while(q!=NULL){
    
    
q=q._PNext;
++count2;
}//计数
p=headA;
q=headB;//重新定到开头
while(p!=q){
    
    
if(p==NULL){
    
    
p=headB;
}else{
    
    
p=p._PNext;
++ret._date;}
if(q==NULL){
    
    
q=headA;
}else
q=q._PNext;
if(ret._date>(count1+count2))
break;//判断没法相等
ret._PNext=p;}
return ret;//相交链表

用法

直接先说无脑一点的:
int main(){
Slist s;
SListInit(&s);//开始有链表了

(SList* s) 类型: &s
(struct SListNode* head)类型:头->_PHead
(SListNode* f)类型:某个节点
(SListInsert)类型:SListInsert(SListFind(&s, 1), 2);

在算法中看函数究竟是返回什么类型的指针,再做决定!
理解清楚!
}

具体的运用请到我Github仓库

猜你喜欢

转载自blog.csdn.net/weixin_51485807/article/details/115017911