C語言動態鏈表數據結構


鏈表的操作增刪改查

typedef int DATA;

struct SNode
{
    DATA data;
    SNode* pNext;
};

SNode* g_head=NULL;//全局變量

//從頭部添加
void AddHead(DATA nNum)
{
    SNode* p = (SNode*)malloc(sizeof(SNode));//C語言的方式
    //SNode* p = new SNode;//C++ 方式
    p->data = nNum;
    p->pNext = g_pHead;

    g_pHead = p;
}


//從尾部添加
void AddTail(DATA nNum)
{
    SNode* p = (SNode*)malloc(sizeof(SNode));//C語言的方式
    pNew->data = nNum;
    pNew->pNext = NULL;

    if (!g_pHead)
    {
        g_pHead = pNew;
        return;
    }

    SNode* p = g_pHead;
    SNode* p1 = NULL;
    while (p)
    {
        p1 = p;
        p= p->pNext;
    }

    //跳出循環時,p1記錄的時最后一個節點,讓最后一個節點的pNext指向新創建的節點
    p = p1;
    p->pNext = pNew;


    //另一種寫法
    //while(p->pNext != NULL)//循環遍歷,當下一個節點為空說明到尾部了
    //    p=p->pNext;
        //p->pNext = pNew;
}

//找到,返回找節點位置;失敗返回-1
int FindNodeIndex(DATA nNum)
{
    SNode* p = g_pHead;
    int i =0;
    while(p)
    {
        if (p->data == nNum)
        {
            return i;
        }
            
        p = p->pNext;
        ++i;
    }

    return -1;
}

//刪除成功返回-1;失敗返回0
int DeleteNode(DATA nNum)
{
    SNode* p = g_pHead;
    SNode* p1 = NULL;//記錄前一個節點

    if (p == NULL)//當前鏈表為空
    {
        return -1;
    }

    //頭節點沒有前一個節點,要特殊處理
    if (p->data == nNum)
    {
        g_pHead = p->pNext;
        delete p;
        return 0;
    }
    while(p)
    {
        if (p->data == nNum)
        {
            //刪除當前節點時,讓當前節點的前一個節點的pNext指向當前節點的后一個節點
            p1->pNext = p->pNext;
            delete p;
            return 0;
        }
        p1= p;//記錄前節點
        p = p->pNext;
    }

    return -1;
}

//修改指定節點的值
void ModifyNode(DATA oldNum,DATA newNum)
{
    SNode* p = g_pHead;
    while(p)//
    {
        if (p->data == oldNum)
        {
            p->data = newNum;
        }
            p = p->pNext;
    }
}

//打印所有節點
void PrintALL()
{
    SNode* p = g_pHead;
    if (p == NULL)
    {
        printf("當前鏈表為空\n");
        return;
    }
    while(p)//
    {
        printf("%d\n",p->data);
        p = p->pNext;
    }
}

//成功返回0;失敗返回-1
int FindNode(DATA nNum)
{
    SNode* p = g_pHead;
    while (p)
    {
        if (p->data == nNum)
        {
            return 0;
        }

        p=p->pNext;
    }
    return -1;
}

//在某個節點之后插入新節點;成功返回0;失敗返回-1
int InsertNode(DATA npos,DATA nNum)
{
    SNode* pNew = new SNode;//C++ 方式
    pNew->data = nNum;
    pNew->pNext = NULL;
    
   SNode* p = g_pHead;

    //if (p->data == npos)//頭結點
    //{
    //    pNew->pNext=p->pNext;//頭節點指向的下一個節點指針放到新節點的pNext
    //    p->pNext=pNew;//頭節點pNext指向新節點

    //    return 0;
    //}

    while(p)
    {
        if (p->data == npos)
        {
            pNew->pNext = p->pNext;
            p->pNext=pNew;

            return 0;
        }
            p = p->pNext;
    }

    return -1;
}

void DeleteAll()
{
    SNode* p = g_pHead;
    SNode* p1 = NULL;
    while(p)
    {
        p1=p;
        p= p->pNext;

        delete p1;
    }

    g_pHead = NULL;
}

int main()
{
    DeleteNode(999);//鏈表為空的時候,刪除要加判斷

    lAddHead(1);
    lAddHead(2);
    AddHead(3);
    puts("修改前");
    PrintALL();
    ModifyNode(2,-88);
    puts("修改后");
    lPrintALL();

    int i = FindNodeIndex(-88);
    if (i >= 0)
    {
        cout << "" << i+1 << "個節點找到" <<endl;
    }

    //刪除節點
    i = DeleteNode(3);//頭部刪除要特殊處理
    if (i == 1)
    {
        cout << "刪除節點成功!" << endl;
    }
    else
    {
        cout << "刪除節點失敗!" << endl;
    }
    PrintALL();

    puts("尾部添加");
    AddTail(4);
    PrintALL();

    //修改節點
    ModifyNode(-88,0);
    puts("插入節點3");
    //插入節點
    i = list.InsertNode(4,3);

    list.PrintALL();

    puts("清空鏈表");
    DeleteAll();
    PrintALL();
  return 0;
}

1.頭部插入

2.尾部插入

3.在指定節點位置后面插入新節點

  例如:在節點2后面插入新節點4

 

中間插入新節點4,讓節點2的pNext賦值給新節點4的pNext,然后讓新節點4的地址賦值給節點2的pNext

 

4.刪除節點

  

注意:如果刪除的是頭節點,要特殊處理,因為頭節點沒有前面的節點,所以頭節點的pNext賦值給g_head;


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM