單鏈表的實現

     學習編程也有一段時間了,可是老是感受,本身缺乏一些什麼東西。編程一味的學習照着別人寫的習慣,沒有本身的思想,是不能有質的提高的。老是感受本身不能作什麼,對待代碼仍是缺乏基本的實現的能力,更不用說什麼技巧算法了。還須要的大量的聯繫。算法

    我打算好好把數據結構的算法,實現如下,老是感受本身,看起來會了,可是實際動手機就寫不出來了。編程

    本身只有不斷的總結,把該記住的東西理解了,才能駕輕就熟。。。。數據結構

公共的頭文件:#include "common.h"函數

#include<string.h>
#include<ctype.h>
#include<malloc.h> /* malloc()等 */
#include<limits.h> /* INT_MAX等 */
#include<stdio.h> /* EOF(=^Z或F6),NULL */
#include<stdlib.h> /* atoi() */
#include<io.h> /* eof() */
#include<math.h> /* floor(),ceil(),abs() */
#include<process.h> /* exit() */
/* 函數結果狀態代碼 */
#define TRUE 1
#define FALSE 0
#define OK 1
#define ERROR 0
#define INFEASIBLE -1  //infeasible
/* #define OVERFLOW -2 由於在math.h中已定義OVERFLOW的值爲3,故去掉此行 */
typedef int Status; /* Status是函數的類型,其值是函數結果狀態代碼,如OK等 */
typedef int Boolean; /* Boolean是布爾類型,其值是TRUE或FALSE */

#include "SingleList.h"學習

#pragma once
#include "common.h"

typedef int ElemType;

//線性表的單鏈表存儲結構
struct LNode
{
    ElemType data;
    LNode* next;
};
typedef struct LNode* LinkList;


class SingleList
{
public:
    SingleList();
    ~SingleList();
public:
    //基本操做12個
    Status InitList(LinkList*);
    Status DestroyList(LinkList*);
    Status ClearList(LinkList);
    Status ListEmpty(LinkList);
    Status ListLength(LinkList);
    Status GetElem(LinkList, int i, ElemType* e);
    Status LocateElem(LinkList L,ElemType e,Status(*compare)(ElemType,ElemType));
    Status PriorElem(LinkList L, ElemType cur_e, ElemType* pre_e);
    Status NextElem(LinkList L, ElemType cur_e,ElemType* next_e);
    Status ListInsert(LinkList L,int i,ElemType e);
    Status ListDelete(LinkList L,int i,ElemType* e);
    Status ListTraverse(LinkList L,void(*vi)(ElemType));
};

"SingleList.cpp"測試

#include "SingleList.h"


SingleList::SingleList()
{
}


SingleList::~SingleList()
{
}

Status SingleList::InitList(LinkList* L)
{
    /*操做結果:構造一個空的線性表L*/
    *L = (LinkList)malloc(sizeof(LNode)); //產生頭結點,並使L指向次頭結點
    if (!*L)
    {
        exit(OVERFLOW);
    }
    (*L)->next = nullptr;//指針域空
    return OK;
}

Status SingleList::DestroyList(LinkList*L)
{
    /*初始條件:線性表L已經存在。操做結果:銷燬線性表*/
    LinkList q;
    while (*L)
    {
        q = (*L)->next;
        free(*L);
        *L = q;
    }
    return OK;
}

Status SingleList::ClearList(LinkList L) /*不改變L*/
{
    /*初始條件:線性表L已經存在。操做結果:將L置爲空表*/
    LinkList p, q;
    p = L->next;/*p指向第一個結點*/
    while (p)   
    {
        q = p->next;  //先記錄下一結點,而後釋放當前結點
        free(p);
        p = q;
    }
    L->next = nullptr;  /*頭結點指針域爲空*/
    return OK;
}

Status SingleList::ListEmpty(LinkList L)
{
    if (L->next==nullptr)
    {
        return OK;
    }
    else
    {
        return ERROR;
    }
}

Status SingleList::ListLength(LinkList L)
{
    int length=0;
    LinkList q=L->next;
    while (q)
    {
        length++;
        q = q->next;
    }
    return length;
}

Status SingleList::GetElem(LinkList L, int i, ElemType* e)
{
    /* L爲帶頭結點的單鏈表的頭指針。當第i個元素存在時,其值賦給e並返回OK,不然返回ERROR */
    LinkList q;
    q = L->next;
    int j = 1; /* j爲計數器 */
    while (q&&j<i)  /* 順指針向後查找,直到p指向第i個元素或p爲空 */
    {
        j++;
        q = q->next;
    }
    if (!q || j>i)  /*第i個元素不存在*/
    {
        return ERROR;
    }
    *e = q->data;   /*取第i個元素*/
    return OK;
}

int SingleList::LocateElem(LinkList L, ElemType e, Status(*compare)(ElemType, ElemType))
{ /* 初始條件: 線性表L已存在,compare()是數據元素斷定函數(知足爲1,不然爲0) */
    /* 操做結果: 返回L中第1個與e知足關係compare()的數據元素的位序。 */
    /*           若這樣的數據元素不存在,則返回值爲0 */
    int i = 0;
    LinkList p = L->next;
    while (p)
    {
        i++;
        if (compare(p->data, e)) /* 找到這樣的數據元素 */
            return i;
        p = p->next;
    }
    return 0;
}

Status SingleList::PriorElem(LinkList L, ElemType cur_e, ElemType *pre_e)
{ /* 初始條件: 線性表L已存在 */
    /* 操做結果: 若cur_e是L的數據元素,且不是第一個,則用pre_e返回它的前驅, */
    /*           返回OK;不然操做失敗,pre_e無定義,返回INFEASIBLE */
    LinkList q, p = L->next; /* p指向第一個結點 */
    while (p->next) /* p所指結點有後繼 */
    {
        q = p->next; /* q爲p的後繼 */
        if (q->data == cur_e)
        {
            *pre_e = p->data;
            return OK;
        }
        p = q; /* p向後移 */
    }
    return INFEASIBLE;
}

Status SingleList::NextElem(LinkList L, ElemType cur_e, ElemType *next_e)
{ /* 初始條件:線性表L已存在 */
    /* 操做結果:若cur_e是L的數據元素,且不是最後一個,則用next_e返回它的後繼, */
    /*           返回OK;不然操做失敗,next_e無定義,返回INFEASIBLE */
    LinkList p = L->next; /* p指向第一個結點 */
    while (p->next) /* p所指結點有後繼 */
    {
        if (p->data == cur_e)
        {
            *next_e = p->next->data;
            return OK;
        }
        p = p->next;
    }
    return INFEASIBLE;
}

Status SingleList::ListInsert(LinkList L, int i, ElemType e) /* 算法2.9。不改變L */
{ /* 在帶頭結點的單鏈線性表L中第i個位置以前插入元素e */
    int j = 0;
    LinkList p = L, s;
    while (p&&j<i - 1) /* 尋找第i-1個結點 */
    {
        p = p->next;
        j++;
    }
    if (!p || j>i - 1) /* i小於1或者大於表長 */
        return ERROR;
    s = (LinkList)malloc(sizeof(struct LNode)); /* 生成新結點 */
    s->data = e; /* 插入L中 */
    s->next = p->next;
    p->next = s;
    return OK;
}

Status SingleList::ListDelete(LinkList L, int i, ElemType *e) /* 算法2.10。不改變L */
{ /* 在帶頭結點的單鏈線性表L中,刪除第i個元素,並由e返回其值 */
    int j = 0;
    LinkList p = L, q;
    while (p->next&&j<i - 1) /* 尋找第i個結點,並令p指向其前趨 */
    {
        p = p->next;
        j++;
    }
    if (!p->next || j>i - 1) /* 刪除位置不合理 */
        return ERROR;
    q = p->next; /* 刪除並釋放結點 */
    p->next = q->next;
    *e = q->data;
    free(q);
    return OK;
}

Status SingleList::ListTraverse(LinkList L, void(*vi)(ElemType))
/* vi的形參類型爲ElemType,與bo2-1.c中相應函數的形參類型ElemType&不一樣 */
{ /* 初始條件:線性表L已存在 */
    /* 操做結果:依次對L的每一個數據元素調用函數vi()。一旦vi()失敗,則操做失敗 */
    LinkList p = L->next;
    while (p)
    {
        vi(p->data);
        p = p->next;
    }
    printf("\n");
    return OK;
}

測試main()spa

#include "common.h"
#include "SingleList.h"


Status comp(ElemType c1, ElemType c2)
{
    //數據元素斷定函數(相等爲True,不然爲FALSE)
    if (c1 == c2)
    {
        return TRUE;
    }
    else
        return FALSE;
}
void visit(ElemType c)
{
    printf("%d", c);
}

int main()
{
    LinkList L;
    ElemType e, e0;
    Status i;
    int  k;
    SingleList s;
    i = s.InitList(&L);
    for (int j = 1; j <= 5;j++)
    {
        i = s.ListInsert(L, 1, j);
    }
    printf("在L的表頭依次插入1~5後:L=");
    s.ListTraverse(L, visit);
    i = s.ListEmpty(L);
    printf("L是否空:i=%d(1:是 0:否)\n", i);
    for (int j = 1; j <= 10;j++)
    {
        s.ListInsert(L,j+5,j);
    }
    printf("在L的表尾依次插入1~10後:L=");
    s.ListTraverse(L,visit);
    s.GetElem(L,5,&e);
    printf("第5個元素的值爲:%d\n", e);
    for (int j = 0; j <= 1; j++)
    {
        k = s.LocateElem(L, j, comp);
        if (k)
            printf("第%d個元素的值爲%d\n", k, j);
        else
            printf("沒有值爲%d的元素\n", j);
    }
    for (int j = 1; j <= 2; j++) /* 測試頭兩個數據 */
    {
        s.GetElem(L, j, &e0); /* 把第j個數據賦給e0 */
        i = s.PriorElem(L, e0, &e); /* 求e0的前驅 */
        if (i == INFEASIBLE)
            printf("元素%d無前驅\n", e0);
        else
            printf("元素%d的前驅爲:%d\n", e0, e);
    }
    for (int j = s.ListLength(L) - 1; j <= s.ListLength(L); j++)/*最後兩個數據 */
    {
        s.GetElem(L, j, &e0); /* 把第j個數據賦給e0 */
        i = s.NextElem(L, e0, &e); /* 求e0的後繼 */
        if (i == INFEASIBLE)
            printf("元素%d無後繼\n", e0);
        else
            printf("元素%d的後繼爲:%d\n", e0, e);
    }
    k = s.ListLength(L); /* k爲表長 */
    for (int j = k + 1; j >= k; j--)
    {
        i = s.ListDelete(L, j, &e); /* 刪除第j個數據 */
        if (i == ERROR)
            printf("刪除第%d個數據失敗\n", j);
        else
            printf("刪除的元素爲:%d\n", e);
    }
    printf("依次輸出L的元素:");
    s.ListTraverse(L, visit);
    s.DestroyList(&L);
    printf("銷燬L後:L=%u\n", L);

    return 0;
}
相關文章
相關標籤/搜索