链表的基本操作

总结一下链表的一些基本操作:

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <time.h>
#define N 12
#define M 20
typedef int elemType;


//定义单链表节点类型
typedef struct Node
{
    elemType element;
    Node *next;
}Node;

//初始化线性表,即置单链表的表头指针为空
void initList(Node **pNode)
{
    *pNode = (Node *) malloc(sizeof(Node));
    (*pNode) ->next = NULL;
    printf("initList 函数执行,初始化成功\n");

}

//创建线性表,此函数输入负数终止读取数据
Node *creatList(Node *pHead)
{
    Node *p1;
    Node *p2 = NULL;
    p1= (Node *)malloc(sizeof(Node)); //申请新节点
    if (p1 == NULL || p2 == NULL)
    {
        printf("内存分配失败\n");
        exit (0);
    }
    memset(p1, 0, sizeof (Node));

    scanf("%d", &p1->element); //输入新节点
    p1->next = NULL;  //新节点的指针置空。
    while(p1->element > 0)
    {
        if(pHead == NULL)  //空表,接入表头
            pHead = p1;
        else
            p2->next = p1;  //非空表,接入表尾
        p2 = p1;
        p1 = (Node *) malloc (sizeof (Node)); //在重新申请一个节点
        if (p1 == NULL || p2 == NULL)
        {
            printf("内存分配失败\n");
            exit (0);
        }
        memset(p1, 0, sizeof(Node));
        scanf("%d",&p1->element);
        p1->next = NULL;

    }   
    printf("creatLise函数执行,链表创建成功\n");
    return pHead;
}

//打印链表,链表的遍历
void printList (Node *pHead)
{
    if(pHead == NULL)
        printf("PrintList 函数执行,链表为空");
    else
    {
        while (NULL != pHead)
        {
            printf("%5d",pHead->element );
            pHead = pHead->next;
        }
        printf("\n");

    }
}

//清除线性表L中的所以元素,即释放单链表L中
//的所有节点,使之成为一个空表
void clearList(Node *pHead)
{
    Node* pNext; //定义一个与pHead相邻节点

    if (pHead == NULL)
    {
        printf("clearList函数执行,链表为空\n");
        return; 
    }
    while(pHead->next != NULL)
    {
        pNext = pHead -> next; //保存下一节点的指针
        free(pHead);
        pHead = pNext;  //表头下移
    }
    printf("clesrList 函数执行,链表已经清除\n");
}

//返回单链表的长度
int sizeList(Node *pHead)
{
    int size = 0;
    while(pHead != NULL)
    {
        size ++;  //遍历链表大小实际比实际链表小1
        pHead = pHead->next;
    }
    printf("sizeList函数执行,链表长度:%d\n",size );
    return size;
}

//检测链表是否为空,若空则返回1,否则返回0
int isEmptyList(Node*pHead)
{
    if(pHead == NULL)
    {
        printf("isEmptyList函数执行,链表为空\n");
        return 1;
    }
    printf("isEmptyList函数执行,链表为空\n");
    return 0;
}

//返回单链表中第pos个节点的元素,若pos超出范围,则停止程序运行
elemType getElemnt(Node *pHead, int pos)
{
    int i = 0;
    if(pos < i)
    {
        printf("pos值非法\n");
        return 0;
    }
    if (pHead == NULL)
    {
        printf("getElement函数执行,链表为空\n");
        return 0;
        //exit (1);  //退出程序
    }
    while(pHead != NULL)
    {
        ++i;
        if(i == pos)
            break;
        pHead = pHead->next; //转移到下一个节点
    }
    if (i < pos)
    {
        printf("getElement函数执行,pos值超出链表长度\n");
        return 0;
    }
    return (pHead->element);

}

//从单链表中查找链表具有给定值X的第一个元素,
//若查找成功则返回该节点data域的存储地址,否则返回NULL。
elemType *getElementAddr(Node * pHead, elemType x)
{
    if (pHead == NULL)
    {
        printf("getElementAddr函数执行,链表为空\n");
        return NULL;
    }
    if (x < 0)
    {
        printf("getElementAddr函数执行,给定的x值不合法\n");
        return NULL;
    }
    //判断是否到链表末尾,以及是否存在所要查找的元素
    while((pHead->element != x ) && (pHead->next != NULL))
    {
        pHead = pHead->next;
    }
    if (pHead->element == x)
        //printf("gerElementAddr函数执行,元素%d的地址为: 0x%x\n",x,&(pHead->element));
    return &(pHead->element);
}

//把单链表中第pos个节点的元素替换为x,若修改成功返回1,否则返回0
int modifyElem(Node *pNode, int pos, elemType x)
{
    Node *pHead;
    pHead = pNode;
    int i = 0 ;
    if (pHead == NULL)
    {
        printf("modifyElem函数执行,链表为空\n");
        return 0;
    }
    if(pos < 1)
    {
        printf("modifyElem函数执行,pos值非法\n");
        return 0;
    }
    while(pHead != NULL)
    {
        ++i;
        if (pos == i)
            break;
        pHead = pHead->next;
    }
    if (i < pos)
    {
        printf("modifyElem函数执行,pos值超出链表长度\n");
        return 0;
    }
    pNode = pHead->next;
    pNode->element = x;
    //printf("modeifyElemAddr函数执行\n");
    return 1;
}


//向单链表的表头插入一个元素
int insertHeadList(Node **pNode,elemType insertElem)
{
    Node *pInsert;
    pInsert = (Node *) malloc (sizeof (Node));
    memset(pInsert,0,sizeof(Node));
    pInsert->element = insertElem;
    pInsert->next = *pNode;
    *pNode = pInsert;
    printf("insertHeadLise函数执行,向表头插入元素成功\n");
    return 1;
}

//向单链表末尾添加一个元素
int insertLastList (Node **pNode, elemType insertElem)
{
    Node *pInsert;
    Node *pHead;
    Node *ptemp; //定义一个临时链表来存放第一个节点。

    pHead = *pNode;
    ptemp = pHead;
    pInsert = (Node *)malloc(sizeof(Node));
    memset(pInsert, 0 ,sizeof(Node));
    pInsert->element = insertElem;

    while(pHead->next != NULL)
    {
        pHead= pHead->next; //找到表末尾
    }
    pHead->next = pInsert;
    *pNode = ptemp;
    printf("insertLastLisr函数执行成功,想链表末尾插入元素成功\n");
    return 1;
}

//向有序单链表中插入元素,不改变链表的有序性
int insertOrderList(Node **pNode, elemType insertElem)
{
    Node *pHead, *ptemp = NULL, *pInsert;
    pHead = *pNode;
    pInsert = (Node *)malloc(sizeof(Node)); //申请一个新的节点
    if(pInsert == NULL)
    {
        printf("内存分配失败,结束程序\n");
        exit(1);
    }
    pInsert->element = insertElem;

    //把新节点插入到表头中
    if (pHead == NULL || insertElem < pHead->element)
    {
        pInsert->next = pHead;
        *pNode = pInsert;
        return 1;
    }
    //顺序查找,找出insertElem的插入位置
    while(pHead != NULL)
    {
        if (insertElem < pHead->element)
            break;
        else
        {
            ptemp = pHead;
            pHead = pHead->next;
        }

    }

    //把x节点插入到ptemp与pHead之间
    pInsert->next = pHead;
    ptemp->next = pInsert;

    return 1;

}

//从单链表中删除表头节点,并把该节点
//的值返回,若删除失败则停止程序运行
elemType deleteFirstList(Node *pHead)
{
    elemType temp;
    Node *pNode;
    pNode = pHead; //暂存表头节点指针,以便回收
    if (pHead == NULL)
    {
        printf("单链表为空,退出程序\n");
        exit (1);
    }
    pHead = pHead->next; //使表头指针指向第二个节点
    temp = pNode->element; //暂存原表头元素,以便返回
    free(pNode);  //回收被删除的表头数据
    return temp; //返回第一个节点的值
}

//从单链表中删除结尾节点并返回它的值,若删除失败则停止程序运行
elemType deleteLastList( Node *pHead)
{
    Node *pNode, *ptemp = NULL;
    elemType lastelement;
    pNode = pHead; //指向表头节点
    if (pHead == NULL)
    {
        printf("链表为空,退出程序\n");
        exit (1);
    }

    while (pNode ->next != NULL)
    {
        ptemp = pNode;
        pNode = pNode->next;  //查找链表末尾
    }

    //若单链表中只有一个节点,则只需要修改表头指针
    if (ptemp == NULL)
        pHead = pHead->next;
    //删除表尾节点
    else 
        ptemp->next = NULL;
    //暂存表尾元素,以便返回
    lastelement = pNode->element;
    free(pNode);
    return lastelement;  //返回表尾元素值
}

//从单链表中删除第pos个节点,并返回它的值,若删除失败接受程序运行
elemType deletePosList (Node *pHead, int pos)
{
    int i = 0;
    Node *pNode, *ptemp = NULL;
    pNode = pHead;
    elemType poselement;
    if (pNode == NULL || pos <= 0)
    {
        printf("单链表为空或者pos值非法\n");
        exit (1);
    }

    /*从单链表中找到第pos个节点*/
    while(pNode != NULL)
    {
        i++;
        if(i = pos)
            break;
        ptemp = pNode;
        pNode = pNode->next;

    }

    if(pNode == NULL)
    {
        printf("pos值非法,退出程序\n"); //链表中不存在第pos个节点
        exit(1);
    }
    //pos =1,删除表头节点
    if (pos == 1)
        pHead = pHead->next;
    /* 否则删除非表头结点,此时cp指向该结点,ap指向前驱结点 */
    else
        ptemp->next = pNode->next;

    poselement = pNode->element;
    free(pNode);
    return poselement;

}

//找到第index个元素,返回节点
Node * findnode( Node *phead, int index)
{
    if(!phead) return NULL;
    Node * pnode = phead;
    while (index --)
    {
        pnode = pnode->next;
        if (!pnode)
            return NULL;

    }
    return pnode;
}

//找到前驱节点
Node * find_preNode(Node *phead, Node *pnode)
{
    if(!pnode) return NULL;
    Node *preNode = phead;
    while (preNode)
    {
        if(preNode->next == pnode)
            return preNode;
        preNode = preNode->next;
    }
    return NULL;
}

//交换链表中的两个元素
void swipList(Node **pHead, int i, int j)
{
    if(!pHead) return;
    //找出节点
    Node *pnode1 = findnode(*pHead, i);
    Node *pnode2 = findnode(*pHead,j);
    //找出前驱节点
    Node *pre1 = find_preNode(*pHead, pnode1);
    Node *pre2 = find_preNode(*pHead, pnode2);

    //相邻的情况
    Node *pBefore = NULL, *pAfter = NULL, *pPre = NULL;
    if (pre2 == pnode1)
    {
        pBefore = pnode1;
        pAfter = pnode2;
        pPre = pre1;
    }
    if (pre1 == pnode2)
    {
        pBefore = pnode2;
        pAfter = pnode1;
        pPre = pre2;
    }
    if (pre2 == pnode1 ||pre1 == pnode2)
    {
        pPre->next = pAfter;
        pBefore->next = pAfter ->next;
        pAfter->next = pBefore;
    }
    else
    {
        //不相邻的情况
        Node *pnext1 = pnode1 ->next;
        Node *pnext2 = pnode2->next;
        pnode1->next = pnode2->next;
        pre1->next = pnode2;
        pre2->next = pnode1;
        pnode2->next = pnext1;
    }


}

//链表的排序
void fastsort(Node **phead, Node *end)
{
    Node *right;
    Node **left_walk, **right_walk;
    Node *pivot, *old;
    int count, left_count, riht_count;
    if(*phead == end)
        return;
    do 
    {
        pivot = *phead;
        left_walk = phead;
        right_walk = &right;
        left_count = riht_count = 0;
        //取第一个节点作为比较的基准点,小于基准点的在左面的子链表中,
        //大于基准的在右边的子链表中
        for (old = (*phead)->next; old != end; old = old ->next)
        {
            if (old->element < pivot->element)
            {
                //小于基准,加入到左边的子链表,继续比较
                ++ left_count;
                *left_walk = old; //把该节点加入到左边的链表中
                left_walk = &(old->next);

            }
            else   //大于基准,加入到右边的子链表,继续比较
            {
                ++riht_count;
                *right_walk = old;
                right_walk = &( old->next);

            }
        }


        //合并链表
        *right_walk = end; //结束右链表
        *left_walk = pivot; //把基准链表置于正确位置
        pivot->next = right; //链表合并

        //对较小的子链表进行快速排序,较大的子链表进行迭代排序
        if (left_walk > right_walk)
        {
            fastsort( &(pivot->next), end);
            end = pivot;
            count = left_count;
        }
        else
        {
            fastsort(phead, pivot);
            phead = &(pivot ->next);
            count = riht_count;
        }

    } while (count >1 );

}

int main()
{
    int a[N];
    int i;
    Node *p , *h , *s;

    initList(&h);
    p = h;


    srand(time(NULL));
    //产生随机数组
    for ( i =0; i < N; i++)
    {
        a[i]=rand() % M + 1;
    }
    printf("随机数序列为:\n");
    for (int i = 0; i < N; i++)
    {
        printf("%5d",a[i]);
        //insertLastList( h, a[i]);
    }
    printf("\n");



    //利用数组初始化链表
    for (int i = 0; i < N; i++)
    {
        s = (Node *)malloc(sizeof(Node));  //申请一个新节点
        memset(s, 0, sizeof(Node));
        s->element = a[i];
        p->next = s;
        p = s;
    }
    p->next = NULL;

    Node * head = h->next;

    int pos = 11;
    int k = getElemnt(head,pos);
    printf("第%d个元素为:%d\n",pos,k);

    printf("链表:\n");
    printList(head); //打印链表

    modifyElem(head, 2, 8);
    printf("将位置3元素替换成8之后的链表:\n");
    printList(head); //打印链表


    swipList( &head, 2, 4);
    printf("交换3,5位置之后的链表:\n");//因为传进去的是不带表头的数据
    printList(head); //打印链表


    //FastSort(&head, 1, sizeList(head) - 1);

    fastsort(&head,p->next);

    printf("快速排序:\n");
    printList(head);

    clearList(h);

   system("pause");
   return 0;
}

这里写图片描述

参考于:http://blog.csdn.net/liuduoqing/article/details/2278492
http://www.jb51.net/article/37300.htm

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值