1. 程式人生 > >資料結構——線性表的鏈式實現

資料結構——線性表的鏈式實現

 記錄一下比較完整的鏈式線性表的函式操作集

語言C++ 環境codeblocks17.01

#include <iostream>
#include <stdio.h>
#include <stdlib.h>
#include <algorithm>

#define Status int
#define ElemType int

using namespace std;

typedef struct LNode //struct link = Link
{
    ElemType data;
    struct LNode *next;
} LNode,*LinkList;

Status InitList (LinkList &L)
{/*初始化*/
    L = new LNode;
    L->next = NULL;
    return 1;
}

Status ListInsert(LinkList &L, int i,ElemType e)
{/*連結串列插入元素e*/
    LNode *p = L;
    int j=0;
    while(p && (j<i-1))
    {
        p = p->next;
        j++;
    }
    if(!p||j>i-1)
        return -1;
    LNode *s;
    s = new LNode;
    s->data = e;
    s->next = p->next;  // s->next = NULL; or s->next = p->next
    p->next = s;
    return 1;

}

Status ListTraverse(LinkList &L)
{/*連結串列遍歷輸出*/
    LNode *p = L;
    p = p->next;
    while(p)
    {
        printf("%d ",p->data);
        p = p->next;
    }
    return 1;
}

Status ListReverse(LinkList &L)
{/*連結串列逆序*/
    if(L==NULL||L->next==NULL)
        return -1;

    LNode* pNext = L->next->next;
    LNode* pNode = L->next;
    LNode* pTemp = L->next->next->next;
    LNode* pFirst = L->next;   // 記錄原連結串列的第一個節點,即逆轉後的tail node

    // 每次處理兩個節點
    while(pNode->next && pNext)
    {
        pNext->next = pNode;    // 迭代逆轉的兩個節點是 pnext pnode
        pNode = pNext;
        pNext = pTemp;

        if(pTemp!=NULL)
            pTemp = pTemp->next;
        else
            ;
    }
    L->next = pNode;    // 頭節點指向新的第一個元素節點
    pFirst->next = NULL;  // tail node = NULL
    return 1;
}

Status ListSort_1(LinkList &L)
{/*使用sort函式時間複雜為(O(nlogn))*/
    int i=0;
    LNode* h = L;

    if(h->next==NULL||h==NULL)
        return -1;
    ElemType* temp = new ElemType[100];     //變數連結串列存放在陣列中

    for(i=0, h=h->next; h; h=h->next,i++)
    {
        temp[i] = h->data;
    }

    sort(temp, temp+i);

    h = L;
    // 資料複製回到list
    for(i=0, h=h->next; h; h=h->next,i++)
    {
        h->data = temp[i];
    }
    return 1;
}

Status ListSort_2(LinkList &L)
{/*線性表的排序,採用氣泡排序,直接遍歷連結串列*/

    LNode* h = L;
    //作為一個臨時量
    LNode* p;
    LNode* p1;
    //如果連結串列為空直接返回
    if (h->next==NULL||h==NULL)
        return-1;

    for (p = L; p->next!=NULL ; p = p->next)
    {
        for (p1 = p; p1->next!=NULL ; p1 = p1->next)
        {
            //如果前面的那個比後面的那個大,就交換它們之間的是資料域
            if (p1->data > p1->next->data)
            {
                ElemType temp = p->data;
                p->data = p1->next->data;
                p1->next->data = temp;
            }
        }
    }
    return 1;
}

Status ListDeleteEvenNum(LinkList &L)
{/*刪除所有偶數元素節點*/
    if (L->next==NULL||L==NULL)
        return-1;

    LNode* p = L;
    LNode* pre; // 前驅結點

    pre = p;
    p = p->next;
    while(p)
    {
        if(p->data%2 == 0)
        {
            pre->next = p->next;
            free(p);
            p = pre->next;
            continue;
        }
        p = p->next;
        pre = pre->next;

    }
    return 1;
}

Status MergeList(LinkList &L1,LinkList &L2)
{/*連結兩個連結串列*/
    if((L1->next==NULL||L1==NULL)&&(L2->next==NULL||L2==NULL))  //兩個都是空連結串列
        return -1;
    LNode* p1;
    p1 = L1->next;

    while(p1->next)
    {
        p1 = p1->next;
    }

    p1->next = L2->next;    // 連結L1和L2

    return 1;
}

Status ListSplitEvenOdd(LinkList &L1, LinkList &L2)
{/*按照奇偶拆分L1 結果是L1存放奇數 L2存放偶數*/
    if (L1->next==NULL||L1==NULL)
        return-1;

    InitList(L2);

    int i=1;
    LNode* p = L1;
    LNode *pre;
    pre = p;
    p = L1->next;

    while(p)
    {
        if(p->data%2 == 0)
        {   // 將L1中的偶數節點插入到L2中
            pre->next = p->next;
            ListInsert(L2,i,p->data);
            i++;
            free(p);
            p = pre->next;
            continue;
        }
        p = p->next;
        pre = pre->next;
    }
    return 1;
}

Status DestroyList(LinkList &L)
{/*銷燬連結串列*/
    if(L==NULL)
      return -1;
    LNode* p;
    // 從L的頭節點開始刪除
    while(L)
    {
        p = L;
        L = L->next;
        free(p);
    }
    return 1;
    // L的頭節點已經不在了
}

Status ClearList(LinkList &L)
{/*清空連結串列*/
    if(L==NULL)
      return -1;
    LNode* p,* l;
    // 從L的首元節開始刪除
    l = L->next;
    while(l)
    {
        p = l;
        l = l->next;
        delete p;
    }
    L->next = NULL; //??????????????????????????????????????
    return 1;
    // L的頭節點還在
}

Status ListEmpty(LinkList &L)
{/*判斷連結串列為空返回1 否則返回0*/
    if(L==NULL)
      return -1;
    else
    {
        if(L->next==NULL)   // 判斷連結串列是否為空
          return 1;
        else
        return 0;
    }
}

Status GetElem(LinkList &L,int i ,ElemType &e)
{/*取得L中第i個元素*/
  LNode *p = L->next;
  int j=1;
  while(p && j<i)
  {
      p = p->next;
      j++;
  }
  if(!p || j<i || i<1)   // 如果p為空或者目標元素不在範圍內,返回錯誤-1
      return -1;
  e = p->data;
  return 1;
}

Status GetElemNode(LinkList &L , ElemType e, LNode* &pe)
{/*取得L中第1個等於e的元素的指標 , 取得返回 1,未找到返回 0*/
  if(L==NULL)
      return -1;
  LNode* p = L->next;
  while(p)
  {
      if(p->data == e)
      {
          pe = p;
          return 1;
      }
      p = p->next;
  }

  return 0;
}

int ListLenght(LinkList &L)
{/*返回連結串列長度*/
    if(L==NULL)
        return -1;
    LNode* p = L;
    int len = 0;
    p = p->next;
    while (p)
    {
      p = p->next;
      len++;
    }
    return len;
}

int compare(ElemType a , ElemType b)
{/*判斷ab的關係,返回一個int來表示ab關係*/
   /* -1 a<b  1 a>b  0 a=b */
    if(a==b)
    return 0;
    else if (a>b)
    return 1;
    else
    return -1;
}

int LocateElem(LinkList &L ,ElemType e,int compare(ElemType , ElemType), int mod)
{/*通過compare()函式 判定e和L中第一個符合mod(compare中ab的關係判定返回值0,1,-1)的元素的位置*/
    if(L==NULL)
      return -1;

    LNode* p = L->next;
    int location=1;
    while(p)
    {
        if(compare(e,p->data)==mod)   // 當e與L中的元素符合mod關係時返回其位置
            return location;
        p = p->next;
        location++;
    }
    return 0;
}

Status NextElem(LinkList &L, ElemType cur_e, LinkList & next_e)
{ /*用next_e返回cur_e的前驅結點 ,cur_e的位置不能在尾元 否則返回0*/
    if(L==NULL)
        return -1;
    int j = 1;
    LNode* p = L->next;
    while(p)
    {
        if(p->data == cur_e)
            {p = p->next; break;}
        p = p->next;
        j++;
    }
    if(p==NULL) // 在尾元
        return 0;
    next_e = p;
    return 1;
}

Status PriorElem(LinkList &L, ElemType cur_e, LinkList & pre_e)
{/*用pre_e返回L中第一個值為cur_e的元素的前驅結點 ,cur_e的位置不能在首元*/
    if(L == NULL)
        return -1;
    int j = 1;
    LNode* P = L->next;
    while(p)
    {
        if(p->data == cur_e)
            break;
        p = p->next;
        j++;
    }
    if(j<2) // 在首元 返回-1
        return -1;
    else if(p==NULL)    // 未找到 返回0
        return 0;
    else
    {
      pre_e = p;    // 找到
      return 1;
    }
}
Status DeleteElem_value(LinkList &L,ElemType e)
{/*刪除L中值為e的所有節點,成功返回1 失敗返回0*/
    if(L==NULL)
        return 0;
    LNode* p = L->next;
    LNode* pre = L;
    while(p)
    {
        if(p->data==e)
        {
            pre->next = p->next;  // 連結要刪除的節點的前後節點
            free(p);    // 釋放節點
            break;
        }
        pre = p;
        p = p->next;
    }
    if(p==NULL)
        return 0;
    else
        return 1;
}

Status DeleteAllElem_value(LinkList &L,ElemType e)
{/*刪除L中值為e的所有節點,成功返回1 失敗返回0*/
    if(L==NULL)
        return 0;
    LNode* p = L->next;
    LNode* pre = L;
    while(p)
    {
        if(p->data==e)
        {
            pre->next = p->next;  // 連結要刪除的節點的前後節點
            free(p);    // 釋放節點
            p = pre->next;
            continue;
        }
        pre = p;
        p = p->next;
    }
    return 1;
}

Status DeleteElem_location(LinkList &L,int location)
{/*刪除L中第location位置的節點,成功返回1 失敗返回0*/
    if(L==NULL)
        return 0;
    LNode* p = L->next;
    LNode* pre = L;
    int j = 1;

    while(p)
    {
        if(j==location)
        {
            pre->next = p->next;  // 連結要刪除的節點的前後節點
            free(p);    // 釋放節點
            break;
        }
        j++;
        pre = p;
        p = p->next;
    }
    if(p==NULL)
        return 0;
    else
        return 1;
}

int main()
{  /*main 測試函式*/
    LNode *L;
    int temp;
    int i = 1;
    InitList(L);

    while(1)
    {
        scanf("%d",&temp);
        if(temp==0)
            break;
        ListInsert(L,i,temp);
        i++;
    }

    ListTraverse(L);

    return 0;

}