单链表基本操作

思维导图

这里写图片描述

SList.h

#pragma once
#include <stdio.h>
#include <assert.h>
#include <stdlib.h>


typedef int DataType;

typedef struct SNode
{
    DataType data;
    struct SNode *_pNext;//保存下个节点的地址

}SNode, *PNode;


void SListInit(PNode* pHead);// 链表的初始化 
void SListPushBack(PNode* pHead, DataType data);// 尾插 
void SListPopBack(PNode* pHead);// 尾删 
void SListPushFront(PNode* pHead, DataType data);// 头插 
void SListPopFront(PNode* pHead);// 头删 
PNode SListFind(PNode pHead, DataType data);// 在链表中查找值为data的元素,找到后返回值为data的结点
void SListInsert(PNode* pHead, PNode pos, DataType data);// 在pos位置插入值为data的结点 
void SListErase(PNode* pHead, PNode pos);// 删除pos位置的结点 
int SListSize(PNode pHead);// 获取链表中节点总数
int SListEmpty(PNode pHead);// 判断链表是否为空 
void SListDestroy(PNode* pHead);// 销毁链表
void PrintfList(PNode pHead);//打印链表

SList.c

#include "SList.h"

//初始化就是将链表头指针赋空,
//注意这里要传头指针的地址才能改变头指针的值
void SListInit(PNode* pHead)
{
    assert(pHead);//判断链表是否存在
    *pHead = NULL;
}
//创建新节点
PNode BuyNewNode(DataType data)
{
    PNode ptr = NULL;
    ptr = (PNode)malloc(sizeof(DataType)+sizeof(PNode));

    if (NULL == ptr)
    {
        printf("BuyNewNode failed!!!\n");
        return NULL;
    }
    //申请成功  
    ptr->data = data;
    ptr->_pNext = NULL;
    return ptr;
}

//打印链表
void PrintfList(PNode pHead)
{
    PNode ptr = pHead;
    if (pHead == NULL)
        return;
    while (ptr)
    {
        printf("%d-->", ptr->data);
        ptr = ptr->_pNext;
    }
    printf("NULL\n");

}

//尾插
void SListPushBack(PNode* pHead, DataType data)
{
    PNode pCur = NULL;
    assert(pHead);//判断链表是否存在

    if (*pHead == NULL)//判断链表是否为空
    {
        *pHead = BuyNewNode(data);//空就让头节点指向新节点
        return;
    }

    //1.先找到链表最后一个节点
    pCur = *pHead;
    while (pCur->_pNext)
    {
        pCur = pCur->_pNext;//朝后走一步
    }
    pCur->_pNext = BuyNewNode(data);

}

//尾删
void SListPopBack(PNode* pHead)
{
    assert(pHead);
    PNode pPre = *pHead;
    PNode pCur = *pHead;

    if (*pHead == NULL)
    {
        printf("链表已空,删除失败!!!\n");
        return;
    }

    //1.只有一个节点
    if (pCur->_pNext == NULL)
    {
        free(*pHead);
        *pHead = NULL;
        return;
    }
    //2.有一个以上节点
    while (pCur->_pNext)
    {
        pPre = pCur;//因为要找到倒数第二个节点,所以每走一步之前先保存
        pCur = pCur->_pNext;
    }
    free(pPre->_pNext);
    pPre->_pNext = NULL;
}

//头插
void SListPushFront(PNode* pHead, DataType data)
{
    PNode ptr = NULL;
    assert(pHead);
    //1.链表为空
    if (NULL == *pHead)
    {
        *pHead = BuyNewNode(data);
        return;
    }

    //2.链表不为空
    ptr = *pHead;//先保存第一个节点地址
    *pHead = BuyNewNode(data);//头指针指向新节点
    (*pHead)->_pNext = ptr;//新节点的_pNext指向原来的头节点

}

//头删
void SListPopFront(PNode* pHead)// 头删
{
    assert(pHead);
    PNode ptr = NULL;
    if (NULL == pHead)
    {
        printf("链表已空,删除失败!!!\n");
        return;
    }

    //1.只有一个节点
    if ((*pHead)->_pNext == NULL)
    {
        free(*pHead);
        *pHead = NULL;
        return;
    }

    //2.有一个以上的节点
    ptr = *pHead;//先保存头节点地址
    *pHead = (*pHead)->_pNext;//头指针朝后走一步;
    free(ptr);//释放原头节点空间
}
//查找为data的节点
PNode SListFind(PNode pHead, DataType data)
{
    PNode ptr = pHead;
    if (NULL == pHead)
    {
        printf("对不起,为空链表!!!\n");
        return NULL;
    }

    while ((ptr) && (ptr->data != data))//ptr中的data不是要找的且不为空就进入循环
    {
        ptr = ptr->_pNext;
    }

    //1.ptr为空,证明找不到
    if (NULL == ptr)
    {
        printf("对不起,找不到!!!\n");
        return NULL;
    }
    else
        return ptr;
}

int SListSize(PNode pHead)
{
    int count = 0;
    while (pHead)
    {
        pHead = pHead->_pNext;
        count++;
    }
    return count;
}

void SListInsert(PNode* pHead, PNode pos, DataType data)
{
    assert(pHead);

    //1.链表为空
    if (NULL == *pHead)
    {
        //1.如果链表为空,插入位置与头节点地址不相同,那么位置不合法
        if (pos == *pHead)
        {
            *pHead = BuyNewNode(data);
            return;
        }
        else
        {
            printf("位置不合法,插入失败!!!\n");
            return;
        }
    }

    //2.链表不为空
    //(1)头插:pos与头节点地址相等
    if (pos == *pHead)
        SListPushFront(pHead, data);
    //(2)pos与头节点位置不相等
    else
    {
        PNode pPre = *pHead;
        PNode pCur = *pHead;
        while ((pCur) && (pCur->_pNext != pos))
        {
            pCur = pCur->_pNext;
        }
        if (pCur == NULL)
        {
            printf("对不起,找不到该节点!!!\n");
            return;
        }
        else
        {
            pCur->_pNext = BuyNewNode(data);//插入新节点
            pCur->_pNext->_pNext = pos;//新节点链接pos处的节点
            pos = pCur->_pNext;//pos指向新节点
        }

    }
}


// 删除pos位置的结点 
void SListErase(PNode* pHead, PNode pos)
{
    assert(pHead);
    PNode ptr = *pHead;

    if (NULL == *pHead)
    {
        printf("链表已空,删除失败!!!\n");
        return;
    }

    //1.只有一个节点
    if ((*pHead)->_pNext == NULL)
    {
        if (*pHead == pos)
        {
            free(pos);
            *pHead = NULL;
            return;
        }

        else
        {
            printf("位置不合法,删除失败!!!\n");
            return;
        }
    }

    //2.有一个以上节点
    //(1)如果pos是头节点
    if (pos == *pHead)
    {
        *pHead = (*pHead)->_pNext;
        free(pos);
        return;
    }

    //(2)不是头结点
    while ((ptr) && (ptr->_pNext != pos) && (pos))
    {
        ptr = ptr->_pNext;
    }

    if ((ptr == NULL) || (pos == NULL))
    {
        printf("节点不存在,删除失败!!!\n");
        return;
    }
    else
    {
        ptr->_pNext = pos->_pNext;//链接起pos的下个节点
        free(pos);
    }
}
// 判断链表是否为空 
int SListEmpty(PNode pHead)
{
    if (pHead)
        return 1;
    return 0;
}

// 销毁链表
void SListDestroy(PNode* pHead)
{
    assert(pHead);
    PNode ptr = *pHead;
    PNode pMsg = *pHead;

    while (ptr)
    {
        ptr = ptr->_pNext;//ptr朝后走
        free(pMsg);//释放pMsg指向的空间

        if (ptr)
            pMsg = ptr;//pMsg跟着ptr走
    }
    *pHead = NULL;
}

test.c

#include "SList.h"
#include <windows.h>


int main()
{
    SNode SList;
    PNode pHead = &SList;
    SListInit(&pHead);// 链表的初始化
    SListEmpty(pHead);// 判断链表是否为空 
    SListInsert(&pHead, pHead, 40);
    PrintfList(pHead);
    //SListPushFront(&pHead, 0);
    //PrintfList(pHead);
    SListPushBack(&pHead, 5);//尾插
    SListPushBack(&pHead, 10);
    SListPushBack(&pHead, 3);
    //PrintfList(pHead);
    //SListPopBack(&pHead);//尾删
    //PrintfList(pHead);
    SListPushFront(&pHead, 0);//头插
    //PrintfList(pHead);
    //SListPopFront(&pHead);//头删
    PrintfList(pHead);
    // 在链表中查找值为data的元素,找到后返回值为data的结点
    SListFind(pHead, 3);
    SListSize(pHead);// 获取链表中节点总数
    SListInsert(&pHead, pHead->_pNext->_pNext , 20);// 在pos位置插入值为data的结点 
    PrintfList(pHead);
    SListErase(&pHead, pHead->_pNext->_pNext);// 删除pos位置的结点
    PrintfList(pHead);
    //SListDestroy(&pHead);// 销毁链表

    system("pause");
    return 0;
}

一个单链表基本操作的问题

10-12

这是我的程序:#includern#includern#includern#define OK 1rn#define ERROR 0rnrnstruct Person rnrn char Name[12];rn char pNum[12];rn;rntypedef struct Person ElemType;rntypedef struct Nodernrn ElemType data;rn struct Node *next;rnNode,*LinkList;rnvoid init_linklist(LinkList *L)/*对单链表进行初始化*/rnrn *L=(LinkList)malloc(sizeof(Node)); /*申请结点空间*/rn (*L)->next=NULL; /*置为空表*/rnrnvoid InElem(ElemType *e)rnrn cout<<"输入姓名:"<>e->Name;rn cout<<"输入号码:"<>e->pNum;rnrnint MatchE(ElemType *x,ElemType *y)rnrn if(x->Name==y->Name&&x->pNum==y->pNum)rn return OK;rn else return ERROR;rnrnvoid CreateFromHead(LinkList L)rn rn Node *s;rn ElemType c;rn int flag=1;rncout<<"头插输入选择:1/t输入数据 /t0/t结束输入!"<>flag;rn InElem(&c);//c=getchar(); rn //if(c!='$')rn //rn s=(Node*)malloc(sizeof(Node)); /*建立新结点s*/rn s->data=c;rn s->next=L->next;/*将s结点插入表头*/rn L->next=s;rn //rn //elsern // flag=0;rn rnrnvoid CreateFromTail(LinkList L)rn rn Node *r, *s;rn ElemType c;rn int flag =1; /*设置一个标志,初值为1,当输入"$"时,flag为0,建表结束*/rn r=L;rn cout<<"尾插输入选择:1/t输入数据 /t0/t结束输入!"<>flag;rn InElem(&c);rn // if(c!='$')rn // rn s=(Node*)malloc(sizeof(Node));rn s->data=c;rn r->next=s;rn r=s;rn // rn // elsern // rn // flag=0;rn /*将最后一个结点的next链域置为空,表示链表的结束*/rn //rn rn rn r->next=NULL;rn rnNode * Get (LinkList L, int i)rn/*在带头结点的单链表L中查找第i个结点,若找到(1≤i≤n),则返回该结点的存储位置; 否则返回NULL*/rn rn int j;rn Node *p;rn p=L;rn j=0; /*从头结点开始扫描*/ rn while ((p->next!=NULL)&&(jnext; /* 扫描下一结点*/rn j++; /* 已扫描结点计数器 */rn rn if(i == j)rn return p; /* 找到了第i个结点 */rn else rn return NULL; /* 找不到,i≤0或i>n */rn rnNode *Locate( LinkList L,ElemType key)rn/*在带头结点的单链表L中查找其结点值等于key的结点,若找到则返回该结点的位置p,否则返回NULL*/ rn rn Node *p;rn p=L->next; /*从表中第一个结点开始 */rn while (p!=NULL)rn rn if (!MatchE(&(p->data),&key))//////////////////rn p=p->next; rn else rn break; /*找到结点值=key时退出循环 */rn rn return p;rn rnint ListLength(LinkList L)rn/*求带头结点的单链表L的长度*/////定义结构体比较函数rn rn Node *p;rn int j;rn p=L->next;rn j=0; /*用来存放单链表的长度*/rn while(p!=NULL)rn rn p=p->next;rn j++;rn rn return j; /*j为求得的单链表长度*/rn rn rnint InsList(LinkList L,int i,ElemType e)rn/*在带头结点的单链表L中第i个位置插入值为e的新结点s*/rn rn Node *pre,*s;rn int k;rn pre=L; rn k=0; /*从"头"开始,查找第i-1个结点*/rn while(pre!=NULL&&knext;rn k=k+1; rn /*查找第i-1结点*/rn if(!pre) /*如当前位置pre为空表已找完还未数到第i个,说明插入位置不合理*/ rn rn printf("插入位置不合理!");rn return ERROR;rn rn s=(Node*)malloc(sizeof(Node)); /*申请一个新的结点S */rn s->data=e; /*值e置入s的数据域*/rn s->next=pre->next; /*修改指针,完成插入操作*/rn pre->next=s;rn return OK;rnrnint DelList(LinkList L,int i,ElemType *e)rn/*在带头结点的单链表L中删除第i个元素,并将删除的元素保存到变量*e中*/rn rn Node *pre,*r;rn int k;rn pre=L;rn k=0;rn while(pre->next!=NULL && knext; rn k=k+1;rn /*查找第i-1个结点*/rn if(!(pre->next)) /* 即while循环是因为p->next=NULL或i<1而跳出的,而是因为没有找到合法的前驱位置,说明删除位置i不合法。*/rn rn printf("删除结点的位置i不合理!");rn return ERROR;rn rn r=pre->next;rn pre->next=pre->next->next; /*修改指针,删除结点r*/rn *e = r->data;rn free(r); /*释放被删除的结点所占的内存空间*/rn printf("成功删除结点!");rn return OK;rnrnrnvoid ClearList(LinkList L)rnrn Node *s,*m;rn m=L->next;rn L->next=NULL;rn s=m->next;rn while(s!=NULL)rn rn free(m);rn m=s;rn s=s->next;rn rn free(s);rnrnvoid DestroyList(LinkList L)rnrn ClearList(L);rn free(L);rnrnvoid main()rnrn int a;rn Node *s;rn ElemType f;rnLinkList l;rninit_linklist(&l);rnCreateFromHead(l);rncout<<"查找元素位置i:"<>a;rnrns=Get(l,a);rncout<data.Name;cout<data.pNum;rncout<<"输入查找的元素:"<data.Name<data.pNum<>a;rncout<<"输入插入元素:"<>a;rnrnDelList(l,a,&f);rncout<

没有更多推荐了,返回首页

私密
私密原因:
请选择设置私密原因
  • 广告
  • 抄袭
  • 版权
  • 政治
  • 色情
  • 无意义
  • 其他
其他原因:
120
出错啦
系统繁忙,请稍后再试