1. 程式人生 > >關於線性連結串列的一些操作

關於線性連結串列的一些操作

#include <string.h>
#include 
<malloc.h>

#pragma once
#define MAXINFOLEN 128

typedef 
struct _ElemType{
    
int  m_nKey; // 關鍵字
char m_sInfo[MAXINFOLEN]; // 訊息
}
 ElemType;
void Elem_Print(ElemType *e);


// Houjian TANG @ 20070330
typedef struct _NodeType
{
    ElemType 
*elem;  // 節點元素指標
struct _NodeType *next; 
// 下一個節點
}
 NodeType, *List;

typedef 
int (*COMPARE)(ElemType *e1, ElemType *e2);

int compare_key(ElemType *e1, ElemType *e2);
int compare_info(ElemType *e1, ElemType *e2);



// 列印一個節點
void LNode_Print(NodeType *e);
// 列印一個連結串列
void List_Print(List L);
// 初始化一個帶頭結點的連結串列,返回連結串列的頭
List List_Init();
// 將元素e插入到連結串列L的pos位置處,如果pos<0或非常大,則插入到最後

void List_Insert(List  L, int pos, ElemType *e);
// 刪除連結串列L的pos處的節點,如果pos值非常大或者pos<0,返回失敗
// 刪除成功返回true,並將被刪除的元素放到e指向的單元中(e!=NULL)
bool List_Delete(List L, int pos, ElemType *e);
int  List_Locate(List L, COMPARE compare, ElemType *e);
List List_GetNode(List L, 
int pos);
bool List_Delete(List L, int pos, ElemType 
*e);
void List_Destroy(List L);
void List_Reverse(List L);
void List_Test();

int main()
{
    List_Test();
    
return0;
}



void List_Test()
{
    List L;
    ElemType e;
    
int i =0;

    L 
= List_Init();
    
// 建立5個節點的連結串列
    printf("Create a link with 5 nodes: ");
    
for (i=0; i<5; i++)    {
        e.m_nKey 
= i;
        sprintf(e.m_sInfo, 
"Elem Node %d", i);
        List_Insert(L, i, 
&e);
    }

    List_Print(L);

    printf(
"Reverse this link: ");
    List_Reverse(L);
    List_Print(L);

    printf(
"Call Search(e.m_nKey==3): ");
    e.m_nKey 
=3;
    i 
= List_Locate(L, compare_key, &e);
    
if (i >=0)    {
        printf(
"founded! p = ");
        LNode_Print(List_GetNode(L, i));
        printf(
"");
        printf(
"Delete this node: ");
        List_Delete(L, i, 
&e);
        List_Print(L);
    }

    
else{
        printf(
"Not founded! ");
    }


    printf(
"Call Search(e.m_sInfo=='Elem Node 4'): ");
    sprintf(e.m_sInfo, 
"Elem Node 4");
    i 
= List_Locate(L, compare_info, &e);
    
if (i >=0)    {
        printf(
"founded! p = ");
        LNode_Print(List_GetNode(L, i));
        printf(
"");
        printf(
"Delete this node: ");
        List_Delete(L, i, 
&e);
        List_Print(L);
    }

    
else{
        printf(
"Not founded! ");
    }


    e.m_nKey 
=30;
    sprintf(e.m_sInfo, 
"an other node");
    printf(
"Insert a node = (%d, '%s') ",
        e.m_nKey, e.m_sInfo);
    List_Insert(L, 
2&e);
    List_Print(L);

    List_Destroy(L);
}



void LNode_Print(NodeType *e)
{
    printf(
"{%pH:  || e=", e);
    Elem_Print(e
->elem);
    printf(
"] next->%pH)", e->next);
}


void List_Print(List L)
{
    printf(
"// ------------------------------ ");
    
while ((L = L->next) != NULL)    {
        LNode_Print(L);
        printf(
"");
    }

    printf(
"------------------------------ // ");
}


// 分配頭節點
List List_Init()
{
    List L 
= (NodeType *)malloc(sizeof(NodeType));
    L
->next = NULL;
    L
->elem = (ElemType *)malloc(sizeof(ElemType));
    
// L->elem = NULL;
    
//L->elem->m_nKey = 0;
    
//L->elem->m_sInfo[0] = 0;
return L;
}


void List_Insert(List L, int pos, ElemType *e)
{
    List p 
= L, lTmp;
    
int i;

    
// 如果是負數,則插入到最後
if (pos <0{
        
while (p->next != NULL)  // 該迴圈是將tail指向列表的末尾
            p = p->next;
    }

    
// 查詢的pos個位置
for (i=0; i<pos; i++)    {
        
if (p->next == NULL) // 如果已經到了末尾,就不繼續了
break;
        p 
= p->next;
    }

    
// 先申請連結串列結點
    lTmp = (NodeType *)malloc(sizeof(NodeType));
    
// 再分配連結串列結點的內容
    lTmp->elem = (ElemType *)malloc(sizeof(ElemType));
    
*(lTmp->elem) =*e;

    
// 注意下面這兩行,實現了連結串列的連線
    lTmp->next = p->next; 
    p
->next = lTmp;
}


bool List_Delete(List L, int pos, ElemType *e)
{
    List p 
= L, q = NULL;
    
int i =0;
    
if (pos <0)
        
returnfalse;
    
for (i=0; i<pos; i++){
        
if (p->next->next == NULL)
            
returnfalse;
        p 
= p->next;
    }


    
// 下面這兩句是去掉q所指向的元素
    q = p->next;
    p
->next = q->next;
    
if (e != NULL)
        
*=*(q->elem);

    
// 注意一定要釋放
    free(q->elem);
    q
->next = NULL;
    q
->elem = NULL;
    free(q);
    
returntrue;
}


void List_Destroy(List L)
{