前言:
从最开始的连链表都建立不来到现在自己补充函数
我从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仓库