1. 程式人生 > 其它 >05. C Pro 摘錄的連結串列基本操作

05. C Pro 摘錄的連結串列基本操作

原文引用:https://blog.csdn.net/qq_42366014/article/details/105000993

#include <stdio.h>
#include <stdlib.h>
#include <stdbool.h>


typedef struct mylist {
  int v;
  struct mylist *next;
}MY_LIST;

void InitList(MY_LIST **pHead);
void InsertItem(MY_LIST *pItem, int a, MY_LIST *pHead);
void PrintList(MY_LIST *pHead);
void DelItem(MY_LIST *pHead, int item);
void CleanMyList(MY_LIST *pHead);
void ReverseMyList(MY_LIST *pHead);
void SortList(MY_LIST *pHead);
MY_LIST *FindElem(MY_LIST *pHead, int a, bool pos);

//初始化一個空連結串列,以及一個連結串列頭節點(非元節點)
void InitList(MY_LIST **pHead) {
  *pHead = (MY_LIST *)malloc(sizeof(MY_LIST));
  if (NULL == *pHead) {
    printf("pHead Failed!\n");
    exit(1);
  }
  (*pHead)->next = NULL;
  return;
}

//連結串列的遍歷
void PrintList(MY_LIST *pHead) {
  if (pHead->next == NULL) {
    printf("Empty List!\n");
    return;
  }
  MY_LIST *temp = pHead->next;   //這個才是:元節點
  while (temp) {
    printf("***Current Item is %d***\n", temp->v);
    temp = temp->next;
  }
}

//查詢給定元素的節點資訊:pos 標記返回當前節點還是前一個節點
MY_LIST *FindElem(MY_LIST *pHead, int a,bool pos) {
  MY_LIST *temp = pHead;
  MY_LIST *prev = NULL;
  while (temp) {
    if (temp->v == a) break;
    prev = temp;
    temp = temp->next;
  }
  return (!pos)?prev:temp;
}

//指定節點位置之後插入新節點,若無則入隊尾
void InsertItem(MY_LIST *pItem, int a, MY_LIST *pHead) {
  MY_LIST *node = (MY_LIST *)malloc(sizeof(MY_LIST));
  node->v = a;
  node->next = NULL;
  //移動指標到pItem,或者到隊尾
  MY_LIST *end = pHead;
  while (end) {
    if (end->next == NULL) break;
    if (end->next == pItem) {
      end = pItem;
      break;
    }
    end = end->next;
  }
  node->next = end->next;
  end->next = node;
  printf("***Add Item is %d***\n", node->v);
  return;
}

//刪除指定元素節點
void DelItem(MY_LIST *pHead, int item) {
  MY_LIST *pItemPrev = FindElem(pHead, item, 0);
  if (pItemPrev == NULL)
  printf("%d is not exists!\n", item);
  MY_LIST *pItem = pItemPrev->next; //當前節點
  pItemPrev->next = pItem->next;   //重置前一節點的next指標
  free(pItem);
  pItem = NULL;
}

//銷燬除頭節點之外的所有連結串列節點
void CleanMyList(MY_LIST *pHead) {
  MY_LIST *temp = pHead->next;
  MY_LIST *pNext = NULL;
  while (temp) {
    pNext = temp->next;
    pHead->next = pNext;
    free(temp);
    temp = pNext;
  }
  if (pHead->next == NULL)
    printf("Clean MyList Done!\n");
  return;
}

//連結串列反轉
void ReverseMyList(MY_LIST *pHead) {
  MY_LIST *cur = pHead->next;
  MY_LIST *curNext = NULL;
  MY_LIST *temp = NULL;
  while (cur) {
    curNext = cur->next;
    cur->next = temp;
    temp = cur;
    cur = curNext;
  }
  pHead->next = temp;
}

//連結串列排序
void swap(int *a, int *b) {
  int temp;
  temp = *a;
  *a = *b;
  *b = temp;
}
void SortList(MY_LIST *pHead) {
  MY_LIST* pPrev = pHead;
  MY_LIST* pEnd = NULL;
  MY_LIST* pCur = NULL;
  while (pHead != pEnd) {
    pPrev = pHead;
    while (pPrev->next != pEnd) {
      pCur = pPrev->next;
      if (pPrev->v < pCur->v) swap(&pPrev->v, &pCur->v);
      pPrev = pPrev->next;
    }
    pEnd = pPrev;
  }
}