赞助

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;

posted @ 2018-08-05 14:56  车臣  阅读(3842)  评论(0编辑  收藏  举报