单链表操作

来源:互联网 发布:淘宝店铺介绍文艺句子 编辑:程序博客网 时间:2024/06/06 13:16

链表的操作(插入、删除),一般需要注意三种情况:1)空链表操作;2)链表首部元素的操作;3)链表中间元素的操作(包括尾部元素)。


#pragma once#ifndef _MY_LIST_H#define _MY_LIST_Htypedef struct node {struct node *pNext;int key;} Node;Node *ListInsertHead(Node *pList, Node *pCur);Node *ListInsertTail(Node *pList, Node *pCur);Node *ListInsert(Node *pList, Node *pCur);Node *ListDeleteHead(Node *pList);Node *ListDeleteTail(Node *pList);Node *ListDelete(Node *pList, Node *pCur);Node *GetNode(Node *pList, int key);Node *ListReserse(Node *pList);Node *ListMerge(Node *pList1, Node *pList2);void PrintList(Node *pList);#endif // !_MY_LIST_H
#include <stdio.h>#include <stdlib.h>#include <string.h>#include "mylist.h"Node *ListInsertHead(Node *pList, Node *pCur){if (pCur == NULL) {return pList;}pCur->pNext = pList;pList = pCur;return pList;}Node *ListInsertTail(Node *pList, Node *pCur){Node *pIter = pList;if (pList == NULL) {pList = pCur;return pList;}while (pIter->pNext != NULL) {pIter = pIter->pNext;}pIter->pNext = pCur;return pList;}// 链表操作,按序插入需要注意三种情况:// 1)链表为空;2)插入首部元素;3)插入中间元素(一般包括尾部元素)。Node *ListInsert(Node *pList, Node *pCur){Node *pIter = pList;// 0)节点为空if (pCur == NULL) {return pList;}// 1)链表为空if (pList == NULL) {pList = pCur;return pList;}// 2)首部插入if (pCur->key < pList->key) {pCur->pNext = pList;pList = pCur;return pList;}// 3)中间插入,包括结尾插入while (pIter->pNext != NULL && pCur->key > pIter->pNext->key) {pIter = pIter->pNext;}pCur->pNext = pIter->pNext;pIter->pNext = pCur;return pList;}Node *ListDeleteHead(Node *pList){Node *pIter = pList;if (pList == NULL) {return pList;}pList = pList->pNext;free(pIter);return pList;}Node *ListDeleteTail(Node *pList){ Node *pIter = pList;if (pList == NULL) {return NULL;}// 只要一个节点if (pList->pNext == NULL) {free(pList);pList = NULL;return pList;}while (pIter->pNext->pNext != NULL) {pIter = pIter->pNext;}free(pIter->pNext);pIter->pNext = NULL;return pList;}// 链表操作,删除指定的节点,需要注意三种情况:// 1)链表为空;2)删除首部元素;3)删除中间元素(一般包括尾部元素)。Node *ListDelete(Node *pList, Node *pCur){Node *pIter = pList;// 1)链表为空,或节点为空if (pList == NULL || pCur == NULL) {return pList;}// 2)首部删除if (pCur->key == pList->key) {pList = pList->pNext;free(pCur);return pList;}// 3)中间删除,包括结尾删除while (pIter->pNext != NULL && pCur->key != pIter->pNext->key) {pIter = pIter->pNext;}// 如果找到,删除该结点if (pIter->pNext != NULL) {// pIter->pNext = pCur->pNext;pIter->pNext = pIter->pNext->pNext;free(pCur);}return pList;}Node *GetNode(Node *pList, int key){Node *pIter = pList;while (pIter != NULL) {if (pIter->key == key) {return pIter;}pIter = pIter->pNext;}return NULL;}Node *ListReserse(Node *pList){Node *pIter = pList;Node *pPrev = NULL;Node *pNext = NULL;while (pIter != NULL) {pNext = pIter->pNext;pIter->pNext = pPrev;  // 翻转pPrev = pIter;         // 移动pIter = pNext;}return pPrev;}Node *ListMerge(Node *pList1, Node *pList2){Node *pList = NULL;Node *pIter = NULL;Node *pIter1 = pList1;Node *pIter2 = pList2;// 为空的情况if (pList1 == NULL)return pList2;if (pList2 == NULL)return pList1;// 确定头部 if (pList1->key < pList2->key) {pList = pList1;pIter1 = pIter1->pNext;} else {pList = pList2;pIter2 = pIter2->pNext;}pIter = pList;while (pIter1 != NULL && pIter2 != NULL) {if (pIter1->key < pIter2->key) {pIter->pNext = pIter1;pIter1 = pIter1->pNext;} else {pIter->pNext = pIter2;pIter2 = pIter2->pNext;}pIter = pIter->pNext;}if (pIter1 != NULL) {pIter->pNext = pIter1;}if (pIter2 != NULL) {pIter->pNext = pIter2;}return pList;}void PrintList(Node *pList){Node *pIter = pList;while (pIter != NULL) {printf("%d\t", pIter->key);pIter = pIter->pNext;}printf("\n");}

可以考虑使用双重指针来简化分类的场景。


#pragma once#ifndef _MY_LIST2_H#define _MY_LIST2_Htypedef struct node {struct node *pNext;int key;} Node;void ListInsertTail2(Node **ppList, Node *pCur);void ListInsert2(Node **ppList, Node *pCur);void ListDeleteTail2(Node **pList);void ListDelete2(Node **ppList, Node *pCur);Node *ListMerge2(Node *pList1, Node *pList2);#endif // !_MY_LIST2_H
#include <stdio.h>#include <stdlib.h>#include <string.h>#include "mylist2.h"void ListInsertTail2(Node **ppList, Node *pCur){Node **ppIter = ppList;if (ppIter == NULL) {return;}while ((*ppIter) != NULL) {ppIter = &((*ppIter)->pNext);}(*ppIter) = pCur;}void ListInsert2(Node **ppList, Node *pCur){Node **ppIter = ppList;if (ppIter == NULL || pCur == NULL) {return;}while ((*ppIter) != NULL && (*ppIter)->key < pCur->key) {ppIter = &((*ppIter)->pNext);}pCur->pNext = (*ppIter);(*ppIter) = pCur;}void ListDeleteTail2(Node **ppList){Node **ppIter = ppList;if (ppIter == NULL || (*ppIter) == NULL) {return;}while (((*ppIter)->pNext) != NULL) {ppIter = &((*ppIter)->pNext);}free(*ppIter);(*ppIter) = NULL;}void ListDelete2(Node **ppList, Node *pCur){Node **ppIter = ppList;if (ppIter == NULL || pCur == NULL) {return;}while ((*ppIter) != NULL && (*ppIter)->key != pCur->key) {ppIter = &((*ppIter)->pNext);}// 如果找到,删除该节点if ((*ppIter) != NULL) {(*ppIter) = (*ppIter)->pNext;free(pCur);}}Node *ListMerge2(Node *pList1, Node *pList2){Node *pList = NULL;Node **ppIter = &pList;Node *pIter1 = pList1;Node *pIter2 = pList2;while (pIter1 != NULL && pIter2 != NULL) {if (pIter1->key < pIter2->key) {(*ppIter) = pIter1;pIter1 = pIter1->pNext;}else {(*ppIter) = pIter2;pIter2 = pIter2->pNext;}ppIter = &((*ppIter)->pNext);}if (pIter1 != NULL) {(*ppIter) = pIter1;}if (pIter2 != NULL) {(*ppIter) = pIter2;}return pList;}
#if 1#include <stdio.h>#include <stdlib.h>#include <string.h>#include "mylist.h"#include "mylist2.h"void PrintArray(int arr[], int n){printf("array: \n");for (int i = 0; i < n; i++) {printf("%d\t", arr[i]);}printf("\n\n");}int main(){int arr[] = { 0, 8, 23, 4, 90, 2, 41, 7 };int arr1[] = { 23, 4, 90, 2, 41 };int arr2[] = { 78, 123, 8, 5, 0 };Node *pList = NULL;Node *pList1 = NULL;Node *pList2 = NULL;Node *pNode = NULL;int i = 0;int len = 0;#if 1len = sizeof(arr) / sizeof(arr[0]);PrintArray(arr, len);// Insertfor (int i = 0; i < len; i++) {pNode = (Node *)malloc(sizeof(Node));if (pNode == NULL) {printf("malloc error\n");return -1;}pNode->pNext = NULL;pNode->key = arr[i];    // pList = ListInsertHead(pList, pNode);    // pList = ListInsertTail(pList, pNode);// pList = ListInsert(pList, pNode);ListInsert2(&pList, pNode);PrintList(pList);}// Deletefor (int i = 0; i < len; i++) {// pList = ListDeleteHead(pList);// pList = ListDeleteTail(pList);ListDeleteTail2(&pList);// pList = ListDelete(pList, GetNode(pList, arr[i]));// ListDelete2(&pList, GetNode(pList, arr[i]));PrintList(pList);// pList = ListReserse(pList);// PrintList(pList);}#endif#if 0for (i = 0; i < sizeof(arr1) / sizeof(arr1[0]); i++) {pNode = (Node *)malloc(sizeof(Node));if (pNode == NULL) {printf("malloc error\n");return -1;}pNode->pNext = NULL;pNode->key = arr1[i];ListInsert2(&pList1, pNode);}PrintList(pList1);for (i = 0; i < sizeof(arr2) / sizeof(arr2[0]); i++) {pNode = (Node *)malloc(sizeof(Node));if (pNode == NULL) {printf("malloc error\n");return -1;}pNode->pNext = NULL;pNode->key = arr2[i];ListInsert2(&pList2, pNode);}PrintList(pList2);pList = ListMerge(pList1, pList2);//pList = ListMerge2(pList1, pList2);PrintList(pList);#endifgetchar();return 0;}#endif




1 0