1. 程式人生 > 其它 >小程式獲取html格式解析亂碼

小程式獲取html格式解析亂碼

技術標籤:Data Structure資料結構

線性表

  • 線性表有兩種儲存結構:順序表,連結串列
  • 儲存密度= 結 點 中 數 據 元 素 所 佔 的 存 儲 量 結 點 所 佔 的 存 儲 量 \frac{結點中資料元素所佔的儲存量}{結點所佔的儲存量}
    順序表的儲存密度=1;連結串列的儲存密度<1。

線性表的順式儲存結構:順序表

順序表的所有資料元素在儲存器中佔有一整塊儲存空間,且兩個邏輯上相鄰的元素在儲存器中的儲存位置也相鄰。

順序表的結構

typedef struct
{
    elemtype data[MaxSize];     //存放線性表中的元素
    int lenth;      //存放線性表的長度
}SQlist;

順序表的建立

void CreateList(SQlist *&L, elemtype a[], int n)
{
    int i = 0;
    int k = 0;       //k為線性表L中的元素個數,也是線性表的長度
    L = (SQlist *)malloc(sizeof(SQlist));
    while(i<n)      //將a中的元素逐個掃描入L
    {
        L->data[k] = a[i];
        k++;
        i++;
    }
    L->length = k;        //L的長度為k
}

初始化順序表

void InitList(SQlist *&L)       //在實際運用中,初始化最好在主函式中進行
{ 
    L = (SQlist *)malloc(sizeof(SQlist));
    L->length = 0;        //線性表的長度初始化為0
}

順序表的銷燬

void DestroyList(SQlist *&L)
{
    free(L);
}

判斷順序表是否為空表

bool ListEmpty(SQlist *L)
{
    return (L->length==0);
}

求順序表的長度

int Length(SQlist L)        //一個沒有什麼存在意義的函式
{
    return(L->length);
}

順序表的輸出

void OutputList(SQlist *L)
{
    for(int i=0;i<L->length;i++)
    {
        printf("%d",L->length);
    }
}

查詢順序表中的某個元素值的下標

int LocateElem(SQlist *L, ElemType e)//查詢順序表中值為e的元素,如果查詢成功,返回元素位序,否則返回0
{
    int i;
    for(i=0;i<L->length;i++)
    {
        if(L->data[i]==e)
        {
            return i+1;  // 下標為i的元素值等於e,返回其位號i+1
        }
    }
    return 0;  //退出迴圈,說明查詢失敗
}

插入元素

void Insert(SQlist *&L,int i,elemtype e)        //在順序表L的第i個位置上插入e
{
    int j = 0;
    if(i<1 || i>L->length+1 || L->length==MaxSize)      //插入不成功的情況
    {
        return ;
    }
    i--;        //將邏輯序號轉為物理序號
    for(j=L->length; j>i; j--)      //將data[i]及後面的元素後移一個位置
    {
        L->data[j]=L->data[j-1];
    }
    L->data[i] = e;       //插入元素e
    L->length++;        //順序表長度增1
}

該演算法的平均時間複雜度為O(n)。

刪除元素

int Delete(SQlist *&L,int i)       //刪除順序表L的第i個元素,並返回被刪除的元素的值
{
    int e;      //存放被刪除的元素
    int j;
    if(i<1 || i>L->length)
    {
        return;
    }
    i--;        //將邏輯序號轉為物理序號
    e = L->data[i];
    for(j=i; j<L->length-1; j++)        //將data[i]之後的元素全部前移一個位置
    {
        L->data[j] = L->data[j+1];
    }
    L->length--;        //順序表長度減一
}

該演算法的平均時間複雜度為O(n)。

int Delete(SQlist*&L,int x)     //刪除順序表中所有值等於x的元素
{
    int k;      //k記錄不等於x的元素的個數
    for(int i=0; i<L->length; i++)
    {
        if(L->data[i]!=x)
        {
            L->data[k] = L->data[i];
            k++;
        }
    }
    L->length = k;
}

該演算法的平均時間複雜度為O(n)。

線性表的鏈式儲存結構:連結串列

  • 不同於順序表,使用連結串列儲存的資料元素,其物理儲存位置是隨機的。
  • 連結串列中每個資料的儲存都由以下兩部分組成:
    1. 資料元素本身,其所在的區域稱為資料域;
    2. 指向直接後繼元素的指標,其所在的區域稱為指標域

單鏈表

單鏈表的結構

typedef struct LNode
{
    int data;
    struct LNode *next;
}LinkNode;

單鏈表的建立

1.頭插法

頭插法圖例

void CreateList(LinkNode *&L,int a[],int n)     //n為結點總個數
{
    LinkNode * s;
    L=(LinkNode *)malloc(sizeof(LinkNode));     //建立頭結點
    L->next=NULL;
    for(int i=0;i<n;i++)
    {
         s=(LinkNode *)malloc(sizeof(LinkNode));        //迴圈建立結點
         s->data = a[i];        //結點賦值
         s->next = L->next;     //設定結點位置:結點位於頭結點之後,原首結點之前
         L->next = s;
    }
}

2.尾插法

 void CreateList(LinkNode *&L,int a[],int n)
 {
    LinkNode *s, *r;        //r為指向尾結點的指標
    L=(LinkNode *)malloc(sizeof(LinkNode));     //建立頭結點
    r=L;        //將r初始化為頭結點
    for(int i = 0; i<n; i++)
    {
        s=(LinkNode *)malloc(sizeof(LinkNode));     //迴圈建立結點
        s->data = a[i];       //結點賦值
        r->next = s;      //設定結點位置:原尾結點r之後
        r = s;        //新的尾結點為r
    }
    r->next=NULL;
 }

單鏈表的銷燬

void DestoryList(LinkNode *& L)
{
    LinkNode *pre = L;      //pre為要刪除的結點,初始化為頭結點
    LinkNode *p = L->next;      //p始終為pre的後繼節點
    while(p!=NULL)
    {
        free(pre);      //刪除結點
        pre = p;        //後移pre
        p = p->next;        //後移p
    }
    free(pre);      //迴圈結束時,pre為尾結點,刪除尾結點
}

判斷單鏈表是否為空表

bool ListEmpty(LinkNode *L)
{
    return(L->next==NULL);
}

求單鏈表的長度

int Length(LinkNode *L)
{
    int count = 0;      //count為計數器
    LinkNode *p = L;      //從頭結點開始
    while(p)
    {
        count++;
        p = p->next;        //後移p
    }
    return count;
}

按下標查詢元素值

根據下標i,查詢對應的元素值並返回。

int GetElement(LinkNode *L,int i)
{
    int e = 0;      //用於儲存下標i對應的元素值
    LinkNode *p = L;
    if(i<=0)
        return 0;       //輸入的下標不大於0,則返回0報錯
    while( p!=NULL && j<i )
    {
        p=p->next;
        j++;
    }
    if(p == NULL)       //如果單鏈表中不存在下標為i的結點或者對應的結點為空
        return 0;
    else
    {
        e = p->data;
        return e;
    }
}

按已知值查詢對應下標

根據已給出的值e,查詢其對應的下標並返回。

int GetElement(LinkNode *L,int e)
{
    int i = 1;      
    LinkNode *p = L->next;      //頭結點下標記為 0,首結點的下標記為 1
    while( p!=NULL && p->data!=e )
    {
        p=p->next;
        i++;
    }
    if(p==NULL)
        return 0;       //如果單鏈表中不存在該值e
    else
        return i;
}

向單鏈表插入元素

將資料元素e插入到下標為i的結點中。

void ListInsert(LinkNode *&L; int i;int e)
{
    int j=0;
    LinkNode *p = L;
    LinkNode *s;
    if( i<=0 )
        return ;
    while( j<i-1 && p!=NULL )       //不斷迴圈直到找到下標為i-1的結點
    {
        p = p->next;
        j++;
    }
    if( p==NULL )
    {
        return ;        //如果不存在下標為i-1的結點,直接停止呼叫
    }
    else
    {
        s=(LinkNode*)malloc(sizeof(LinkNode));      //建立新的結點
        s->data = e;        //新結點的賦值
        s->next = p->next;      //新結點s位於p的下一個結點之前
        p->next = s;        //新結點s位於p之後
        return ;
    }
}

刪除資料元素

刪除下標為i的結點。

void ListDelete(LinkNode *&L; int i)
{
    int j=0;
    LinkNode *p = L;
    LinkNode *s;
    if( i<=0 )
        return ;
    while( j<i-1 && p!=NULL )       //不斷迴圈直到找到下標為i-1的結點
    {
        p = p->next;
        j++;
    }
    if( p==NULL )
    {
        return ;        //如果不存在下標為i-1的結點,直接停止呼叫
    }
    else
    {
        s = p->next;        //p的下一個結點即為要刪除的結點
        p->next = p->next->next;        //將p的next指標指向被刪除結點的下一個結點
        free(s);
        return ;
    }
}

雙鏈表

雙鏈表的結構

typedef struct DNode
{
    int data;
    struct DNode *prior;        //指向前驅結點
    struct DNode *next;     //指向後繼結點
}DLinkNode;

雙鏈表的建立

1.頭插法

void CreateList(DLinkNode *&L,int a[],int n)
{
    DLinkNode *s;
    L = (DLinkNode*)malloc(sizeof(DLinkNode));      //建立頭結點
    L->prior = L->next = NULL;
    for(int i=0; i<n; i++)
    {
        s = (DLinkNode*)malloc(sizeof(DLinkNode));      //迴圈建立新結點
        s->data = a[i];     //新結點賦值
        s->next = L->next;      //每個新結點都位於頭結點之後
        if(L->next!=NULL)
        {
            L->next = L->prior = s;     // 若頭結點的後繼結點不為空,則頭結點的後繼結點的前驅結點為新結點
        }
        L->next = s;      //頭結點的新後繼節點為剛建立的s結點
        s->prior = L;       //剛建立的s結點的前驅結點為頭結點
    }
}

2.尾插法

void CreateList(DLinkNode *&L,int a[],int n)
{
    DLinkNode *s,*r;       //尾插法必備兩個指標
    L = (DLinkNode*)malloc(sizeof(DLinkNode));      //建立頭結點
    L->prior = L->next = NULL;
    r = L;        //r始終指向尾結點,初始化為頭結點
    for(int i=0; i<n; i++)
    {
        s = (DLinkNode*)malloc(sizeof(DLinkNode));      //迴圈建立新結點
        s->data = a[i];     //新結點賦值
        r->next = s;        //尾結點的後繼結點為新結點s
        s->prior = r;       //新結點s的前驅結點為原尾結點r
        r = s;      //s成為新的尾結點
    }
}

迴圈連結串列

迴圈連結串列圖例

迴圈單鏈表的建立

    LinkNode *(LinkNode *&L,int a[],int n)
    {
        LinkNode *p;
        LinkNode *s;
        L = (LinkNode*)malloc(sizeof(LinkNode));
        L->next = NULL;
        s=L;
        for(int i=0; i<n; i++)
        {
            p=(LinkNode*)malloc(sizeof(LinkNode));
            p->data = a[i];
            s->next = p;
            s = p;
        }
        s->next = L;
        return L;
    }