什么是链表,链表的分类? 链表是一种物理存储结构上非连续 非顺序的存储结构,数据元素的逻辑顺序是通过链表中的指针链接次序实现的. 链表的分类多样,一下情况组合起来有8中结构 1.单向 双向 2.带头 不带头 3.循环 非循环
单链表的基本操作
#pragma once typedef int SDataType; typedef struct SListNode { SDataType _data; struct SListNode* _pNext; }Node, *PNode; typedef struct SList { PNode _pHead;//指向链表中的第一个结点 }SList; void SListInit(SList* s); void SListPushBack(SList* s, SDataType data); void SListPopBack(SList* s); void SListPushFront(SList* s, SDataType data); void SListPopFront(SList* s); void SListInsert(PNode pos, SDataType data); void SListErase(SList* s, PNode pos); PNode SListFind(SList* s, SDataType data); int SListSize(SList* s); int SListEmpty(SList* s); void SListRemove(SList* s, SDataType data); void SListRemoveAll(SList* s, SDataType data); void SListClear(SList* s); void SListDestroy(SList* s); void TestSList(); #include<stdio.h> #include"SList.h" #include<stdlib.h> #include<malloc.h> #include<assert.h> void SListInit(SList* s) { assert(s); s->_pHead = NULL; } PNode BuySListNode(SDataType data) { PNode pNewNode = (PNode)malloc(sizeof(Node)); if (NULL == pNewNode) { assert(0); return NULL; } pNewNode->_data = data; pNewNode->_pNext = NULL; return pNewNode; } 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 (NULL == s->_pHead) { return; } else if (NULL == s->_pHead->_pNext) { //一个结点 free(s->_pHead); s->_pHead = NULL; } else { //多个结点 PNode pPre = NULL; PNode pCur = s->_pHead; 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); pNewNode->_pNext = s->_pHead; s->_pHead = pNewNode; } void SListPopFront(SList* s) { assert(s); if (NULL == s->_pHead) { return; } PNode pDelNode = s->_pHead; s->_pHead = pDelNode->_pNext; free(pDelNode); } void SListInsert(PNode pos, SDataType data) { if (pos == NULL) { return; } else { PNode pNewNode = BuySListNode(data); pNewNode->_pNext = pos->_pNext; pos->_pNext = pNewNode; } } 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; } if (pPrePos) { pPrePos->_pNext = pos->_pNext; } } free(pos); } 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; } int SListSize(SList* s) { assert(s); PNode pCur = s->_pHead; int count = 0; while (pCur) { count++; pCur = pCur->_pNext; } return count; } int SListEmpty(SList* s){ assert(s); return NULL == s->_pHead; } //删除链表中第一个知我data的结点 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; } } } void SListRemoveAll(SList* s, SDataType data) { if (s->_pHead == NULL) { return ; } PNode pPre = NULL; PNode pCur = s->_pHead; while (pCur) { if (pCur->_data == data) { if (pPre == NULL) { //第一个结点 s->_pHead = pCur->_pNext; free(pCur); pCur = s->_pHead; } else { //非第一个结点 pPre->_pNext = pCur->_pNext; free(pCur); pCur = pPre->_pNext; } } else { pPre = pCur; pCur = pCur->_pNext; } } } void SListClear(SList* s) { assert(s); s->_pHead = NULL; } void SListDestroy(SList* s) { assert(s); s->_pHead = NULL; } void PrintSList(SList* s) { assert(s); PNode pCur = s->_pHead; while (pCur) { printf("%d--->", pCur->_data); pCur = pCur->_pNext; } printf("NULL\n"); } void TestSList() { SList s; SListInit(&s); SListPushBack(&s, 1); SListPushBack(&s, 2); SListPushBack(&s, 3); SListPushBack(&s, 4); SListPushBack(&s, 5); PrintSList(&s); SListPopBack(&s); PrintSList(&s); SListPopBack(&s); PrintSList(&s); SListPopBack(&s); PrintSList(&s); SListPopBack(&s); PrintSList(&s); SListPopBack(&s); PrintSList(&s); SListPushFront(&s, 1); PrintSList(&s); SListPushFront(&s, 2); PrintSList(&s); SListPushFront(&s, 3); PrintSList(&s); SListPushFront(&s, 4); PrintSList(&s); SListPushFront(&s, 5); PrintSList(&s); /*SListPopFront(&s); PrintSList(&s); SListPopFront(&s); PrintSList(&s); SListPopFront(&s); PrintSList(&s); SListPopFront(&s); PrintSList(&s); SListPopFront(&s); PrintSList(&s);*/ //void SListInsert(PNode pos, SDataType data) SListInsert(SListFind(&s, 2), 6); PrintSList(&s); SListErase(&s, SListFind(&s, 6)); PrintSList(&s); printf("%d\n", SListSize(&s)); if (SListEmpty(&s)) { printf("链表为空\n"); } else { printf("链表非空\n"); } SListInsert(SListFind(&s, 2), 5); PrintSList(&s); SListRemoveAll(&s,5); PrintSList(&s); SListDestroy(&s); }