線性表

線性表:順序表和鏈表六種基本操作:

  1. InitList(&L)            //構造一個空的線性表L

  2. ListLength(L)           //獲取線性表L的元素個數

  3. GetNode(L, i)           //獲取線性表L第i個元素

  4. LocateNode(L, e)        //查找線性表值爲e的元素的位置

  5. ListInsert(L, i, &e)    //在線性表L的第i個位置插入元素e

  6. DeleteNode(L, i)        //刪除線性表L的第i個元素

一、順序表

#define OK 1
#define ERROR -1
#define MAX_SIZE 100    //MAX_SIZE大小需根據具體情況而定,這裏假設是100
#typedef int Status;
#typedef int ElemType;
typedef struct sqlist{
    ElemType Elem_array[MAX_SIZE];
    int length;
}SqList;

1.1 初始化

Status Init_SqList(SqList *L)
{
    L->Elem_array = (ElemType *)malloc(MAX_SIZE*sizeof(ElemType));
    if(!L->Elem_array)
        return ERROR;
    else
    {
        L->length = 0;
        return OK;
    }
}

1.2 查找

int Locate_SqList(SqList *L, ElemType x) 
{ 
    int i=0; 
    while(i<L->length) 
        if(L_Elem_array[i] != x) 
            i++; 
        else 
            return ++i;                    //要查找的值在線性表L第++i個位置 
     if(i>L->length) 
    { 
        printf(“要刪除的數據元素不存在!\n”);
        return ERROR; 
    }
}

1.3 插入

Status Insert_SqList(SqList *L, int i, ElemType e) //在順序表L中第i個位置插入元素e
{
    int j;
    if(i<0||i>L->length-1)
        return ERROR;
    if(L->length>=MAX_SIZE)
    {
        printf("線性表溢出!\n");
        return ERROR;
    }
    for(j=L->length-1; j>=i-1; --j)
        L->Elem_array[j+1] = L->Elem_array[j]; //i-1位置以後的所以結點後移
    L->Elem_array[i-1] = e; //在i-1位置插入結點e
    L->length++;
    return OK;
}

1.4 刪除

ElemType Delete_SqList(SqList *L, int i)
{
    int k;
    ElemType x;
    if(L->length == 0)
    {
        printf("線性表L爲空!\n");
        return ERROR;
    }
    else if(i<1||i>L->length)
    {
        printf("要刪除的數據元素不存在!\n");
        return ERROR;
    }
    else
    {
        x = L->Elem_array[i-1];                      //保存結點的值
        for(k=i; k<L->length; k++)
            L->Elem_array[k-1] = L->Elem_array[k];  //i位置以後的所有結點前移
        L->length--;
        return x;
    }
}

二、單鏈表

typedef struct Lnode{
    ElemType data;        //數據域,保存結點的值
    struct Lnode *next;   //指針域
}LNode;                  //結點類型

2.1 頭插入法建表

/*頭插入法創建單鏈表,鏈表的頭結點head作爲返回值*/
LNode *create_LinkList(void)
{
    int data;
    LNode *head, *p;
    head = (LNode *)malloc(sizeof(LNode));
    head->next = NULL;                        //創建單鏈表頭結點head
    while(1)
    {
        scanf("%d", &data);                  //data值和類型可以根據具體情況得到
        if(data == 32767)                    //32767定義爲判斷創建鏈表結束條件
            break;
        p = (LNode *)malloc(sizeof(LNode));
        p->data = data;                      //數據域賦值
        p->next = head->next;
        head->next = p;                      //鉤鏈,新創建的結點總是作爲第一個結點
    }
    return head;
}

2.2 尾插入法建表

/*尾插入法創建單鏈表,鏈表的頭結點head作爲返回值*/
LNode *create_LinkList(void)
{
    int data;
    LNode *head, *p, *q;
    head = p = (LNode *)malloc(sizeof(LNode));
    p->next = NULL;                         //創建單鏈表頭結點head
    while(1)
    {
        scanf("%d", &data);                 //data值和類型可以根據具體情況得到
        if(data == 32767)                   //32767定義爲判斷創建鏈表結束條件
            break;
        q = (LNode *)malloc(sizeof(LNode));
        q->data = data;                     //數據域賦值
        q->next = p->next;
        p->next = q;
        p = q;                              //鉤鏈,新創建的結點總是作爲第一個結點
    }
    return head;
}

2.3 按序號查找

Elem_Type Get_Node(LNode *L, int i)  //在單鏈表L中查找第i個結點
{
    int j;
    LNode *p;
    p = L->next;
    j = 1;         //使p指向第一個結點
    while(p!=NULL && j<i)   //p爲NULL表示i太大;j>i表示i爲0;
    {
        p = p->next;
        j++;       //移動指針p,j計數
    }
    if(j!=i)
        return -32768;
    else
        return p->data;
}

2.4 按值查找

LNode *Locate_Node(LNode *L, int key)  //在單鏈表L中查找值爲key的結點
{
    LNode *p = L->next;
    while(p!=NULL && p->data != key)
        p = p->next;
    if(p->data == key)
        return p;
    else
    {
        printf("所要查找的結點不存在!\n");
        return NULL;
    }
}

2.5 插入

/*在以L爲頭結點的單鏈表的第i個位置插入值爲e的結點*/
void Insert_LNode(LNode *L, int i, ElemType e)
{
    int j = 0;
    LNode *p, *q;
    p = L->next;
    while(p!=NULL && j<i-1)
    {
        p = p->next;
        j++;
    }
    if(j!=i-1)
        printf("i太大或i爲0!\n");
    else
    {
        q = (LNode *)malloc(sizeof(LNode));
        q->data = e;
        q->next = p->next;
        p->next = q;
    }
}

2.6 按序號刪除

/*刪除以L爲頭結點的單鏈表中的第i個結點*/
void Delete_LinkList(LNode *L, int i)
{
    int j=1;
    LNode *p = L, *q = L->next;
    while(p->next!=NULL && j<i)
    {
        p = q;
        q = q->next;
        j++;
    }
    if(j!=i)
        printf("i太大或i爲0!\n");
    else
    {
        p->next = q->next;
        free(q);
    }
}

2.7 按值刪除

/*刪除以L爲頭結點的單鏈表中值爲key的第一個結點*/
void Delete_LinkList(LNode *L, int key)
{
    LNode *p = L, *q = L->next;
    while(q!=NULL && q->data!=key)
    {
        p = q;
        q = q->next;
    }
    if(q->data == key)
    {
        p->next = q->next;
        free(q);
    }
    else
        printf("所要刪除的結點不存在!\n");
}
/*按值刪除值爲key的所有結點*/
void Delete_LinkList_Node(LNode *L, int key)
{
    LNode *p = L, *q = L->next;
    while(q!=NULL)
    {
        if(q->data==key)
        {
            p->next = q->next;
            free(q);
            q = p->next;
        }
        else
        {
            p = q;
            q = q->next;
        }
    }
}
/*刪除以L爲頭結點的單鏈表中所有值相同的結點*/
void Delete_Node_value(LNode *L)
{
    LNode *p = L->next, *q, *ptr;
    while(p!=NULL)                    //檢查鏈表中所有結點
    {
        q = p;
        ptr = p->next;
        while(ptr != NULL)            //檢查結點p的所有後繼結點ptr
        {
            if(ptr->data == p->data)
            {
                q->next = ptr->next;
                free(ptr);
                ptr = q->next;
            }
            else
            {
                q = ptr;
                ptr = ptr->next;
            }
        }
        p = p->next;
    }
}

2.8 合併

/*合併以La,Lb爲頭結點的兩個有序單鏈表*/
LNode *Merge_LinkList(LNode *La, LNode *Lb)
{
    LNode *Lc, *pa, *pb, *pc, *ptr;
    Lc = La;
    pc = La;
    pa = La->next;
    pb = Lb->next;
    while(pa!=NULL &&pb!=NULL)
    {
        //將pa所指的結點合併,pa指向下一個結點
        if(pa->data < pb->data)
        {
            pc->next = pa;
            pc = pa;
            pa = pa->next;
        }
        
        //將pb所指的結點合併,pb指向下一個結點
        if(pa->data > pb->data)
        {
            pc->next = pb;
            pc = pb;
            pb = pb->next;
        }
        
        //將pa所指的結點合併,pb所指的結點刪除
        if(pa->data == pb->data)
        {
            pc->next = pa;
            pc = pa;
            pa = pa->next;
            ptr = pb;
            pb = pb->next;
            free(ptr);
        }
    }
    
    if(pa != NULL)
        pc->next = pa;
    else
        pc->next = pb;   //將剩餘的結點鏈上
    free(Lb);
    return Lc;
}

三、循環鏈表

判斷是否空鏈表:   head->next == head;
判斷是否表尾結點: p->next == head;

四、雙向鏈表

typedef struct Dulnode{
    ElemType data;
    struct Dulnode *prior, *next;
}DulNode;

4.1 插入

  1. 插入時僅僅指出直接前驅結點,鉤鏈時必須注意先後次序是:“先右後左”。部分語句組如下:
    S = (DulNode *)malloc(sizeof(DulNode));
    S->data = e;
    S->next = p->next;
    p->next->prior = S;
    p->next = S;
    S->prior = p;
  2. 插入時同時指出直接前驅結點p和直接後繼結點q,鉤鏈時無須注意先後次序。部分語句組如下:

    S = (DulNode *)malloc(sizeof(DulNode));
    S->data = e;
    p->next = S;
    S->next = q;
    S->prior = p;
    q->prior = S;

4.2 刪除

設要刪除的結點爲p,刪除時可以不引人新的輔助指針變量,可以直接先斷鏈,再釋放結點。部分語句組如下:

p->prior->next = p->next;
p->next->prior = p->prior;
free(p);


 

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章