• 单链表


    1.

    最近在复习数据结构,想把数据结构里面涉及的都自己实现一下,完全是用C语言实现的。
    
    自己编写的不是很好,大家可以参考,有错误希望帮忙指正,现在正处于编写阶段,一共将要实现19个功能。到目前我只写了一半,先传上来,大家有兴趣的可以帮忙指正,谢谢
    
    在vs2010上面编译运行无错误。
    
    每天都会把我写的新代码添加到这个里面。直到此链表完成。
    #include "stdafx.h"
    #include "stdio.h"
    #include <stdlib.h>
    #include "string.h"
     
    typedef int elemType ;
     
    /************************************************************************/
    /*             以下是关于线性表链接存储(单链表)操作的18种算法        */
     
    /* 1.初始化线性表,即置单链表的表头指针为空 */
    /* 2.创建线性表,此函数输入负数终止读取数据*/
    /* 3.打印链表,链表的遍历*/
    /* 4.清除线性表L中的所有元素,即释放单链表L中所有的结点,使之成为一个空表 */
    /* 5.返回单链表的长度 */
    /* 6.检查单链表是否为空,若为空则返回1,否则返回0 */
    /* 7.返回单链表中第pos个结点中的元素,若pos超出范围,则停止程序运行 */
    /* 8.从单链表中查找具有给定值x的第一个元素,若查找成功则返回该结点data域的存储地址,否则返回NULL */
    /* 9.把单链表中第pos个结点的值修改为x的值,若修改成功返回1,否则返回0 */
    /* 10.向单链表的表头插入一个元素 */
    /* 11.向单链表的末尾添加一个元素 */
    /* 12.向单链表中第pos个结点位置插入元素为x的结点,若插入成功返回1,否则返回0 */
    /* 13.向有序单链表中插入元素x结点,使得插入后仍然有序 */
    /* 14.从单链表中删除表头结点,并把该结点的值返回,若删除失败则停止程序运行 */
    /* 15.从单链表中删除表尾结点并返回它的值,若删除失败则停止程序运行 */
    /* 16.从单链表中删除第pos个结点并返回它的值,若删除失败则停止程序运行 */
    /* 17.从单链表中删除值为x的第一个结点,若删除成功则返回1,否则返回0 */
    /* 18.交换2个元素的位置 */
    /* 19.将线性表进行快速排序 */
     
     
    /************************************************************************/
    typedef struct Node{    /* 定义单链表结点类型 */
        elemType element;
        Node *next;
    }Node;
     
     
    /* 1.初始化线性表,即置单链表的表头指针为空 */
    void initList(Node **pNode)
    {
        *pNode = NULL;
        printf("initList函数执行,初始化成功
    ");
    }
     
    /* 2.创建线性表,此函数输入负数终止读取数据*/
    Node *creatList(Node *pHead)
    {
        Node *p1;
        Node *p2;
     
        p1=p2=(Node *)malloc(sizeof(Node)); //申请新节点
        if(p1 == NULL || p2 ==NULL)
        {
            printf("内存分配失败
    ");
            exit(0);
        }
        memset(p1,0,sizeof(Node));
     
        scanf("%d",&p1->element);    //输入新节点
        p1->next = NULL;         //新节点的指针置为空
        while(p1->element > 0)        //输入的值大于0则继续,直到输入的值为负
        {
            if(pHead == NULL)       //空表,接入表头
            {
                pHead = p1;
            }
            else               
            {
                p2->next = p1;       //非空表,接入表尾
            }
            p2 = p1;
            p1=(Node *)malloc(sizeof(Node));    //再重申请一个节点
            if(p1 == NULL || p2 ==NULL)
            {
            printf("内存分配失败
    ");
            exit(0);
            }
            memset(p1,0,sizeof(Node));
            scanf("%d",&p1->element);
            p1->next = NULL;
        }
        printf("creatList函数执行,链表创建成功
    ");
        return pHead;           //返回链表的头指针
    }
     
    /* 3.打印链表,链表的遍历*/
    void printList(Node *pHead)
    {
        if(NULL == pHead)   //链表为空
        {
            printf("PrintList函数执行,链表为空
    ");
        }
        else
        {
            while(NULL != pHead)
            {
                printf("%d ",pHead->element);
                pHead = pHead->next;
            }
            printf("
    ");
        }
    }
     
    /* 4.清除线性表L中的所有元素,即释放单链表L中所有的结点,使之成为一个空表 */
    void clearList(Node *pHead)
    {
        Node *pNext;            //定义一个与pHead相邻节点
     
        if(pHead == NULL)
        {
            printf("clearList函数执行,链表为空
    ");
            return;
        }
        while(pHead->next != NULL)
        {
            pNext = pHead->next;//保存下一结点的指针
            free(pHead);
            pHead = pNext;      //表头下移
        }
        printf("clearList函数执行,链表已经清除
    ");
    }
     
    /* 5.返回单链表的长度 */
    int sizeList(Node *pHead)
    {
        int size = 0;
     
        while(pHead != NULL)
        {
            size++;         //遍历链表size大小比链表的实际长度小1
            pHead = pHead->next;
        }
        printf("sizeList函数执行,链表长度 %d 
    ",size);
        return size;    //链表的实际长度
    }
     
    /* 6.检查单链表是否为空,若为空则返回1,否则返回0 */
    int isEmptyList(Node *pHead)
    {
        if(pHead == NULL)
        {
            printf("isEmptyList函数执行,链表为空
    ");
            return 1;
        }
        printf("isEmptyList函数执行,链表非空
    ");
     
        return 0;
    }
     
    /* 7.返回单链表中第pos个结点中的元素,若pos超出范围,则停止程序运行 */
    elemType getElement(Node *pHead, int pos)
    {
        int i=0;
     
        if(pos < 1)
        {
            printf("getElement函数执行,pos值非法
    ");
            return 0;
        }
        if(pHead == NULL)
        {
            printf("getElement函数执行,链表为空
    ");
            return 0;
            //exit(1);
        }
        while(pHead !=NULL)
        {
            ++i;
            if(i == pos)
            {
                break;
            }
            pHead = pHead->next; //移到下一结点
        }
        if(i < pos)                  //链表长度不足则退出
        {
            printf("getElement函数执行,pos值超出链表长度
    ");
            return 0;
        }
     
        return pHead->element;
    }
     
    /* 8.从单链表中查找具有给定值x的第一个元素,若查找成功则返回该结点data域的存储地址,否则返回NULL */
    elemType *getElemAddr(Node *pHead, elemType x)
    {
        if(NULL == pHead)
        {
            printf("getElemAddr函数执行,链表为空
    ");
            return NULL;
        }
        if(x < 0)
        {
            printf("getElemAddr函数执行,给定值X不合法
    ");
            return NULL;
        }
        while((pHead->element != x) && (NULL != pHead->next)) //判断是否到链表末尾,以及是否存在所要找的元素
        {
            pHead = pHead->next;
        }
        if((pHead->element != x) && (pHead != NULL))
        {
            printf("getElemAddr函数执行,在链表中未找到x值
    ");
            return NULL;
        }
        if(pHead->element == x)
        {
            printf("getElemAddr函数执行,元素 %d 的地址为 0x%x
    ",x,&(pHead->element));
        }
     
        return &(pHead->element);//返回元素的地址
    }
     
    /* 9.把单链表中第pos个结点的值修改为x的值,若修改成功返回1,否则返回0 */
    int modifyElem(Node *pNode,int pos,elemType x)
    {
        Node *pHead;
        pHead = pNode;
        int i = 0;
     
        if(NULL == pHead)
        {
            printf("modifyElem函数执行,链表为空
    ");
        }
        if(pos < 1)
        {
            printf("modifyElem函数执行,pos值非法
    ");
            return 0;
        }
        while(pHead !=NULL)
        {
            ++i;
            if(i == pos)
            {
                break;
            }
            pHead = pHead->next; //移到下一结点
        }
        if(i < pos)                  //链表长度不足则退出
        {
            printf("modifyElem函数执行,pos值超出链表长度
    ");
            return 0;
        }
        pNode = pHead;
        pNode->element = x;
        printf("modifyElem函数执行
    ");
         
        return 1;
    }
     
    /* 10.向单链表的表头插入一个元素 */
    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("insertHeadList函数执行,向表头插入元素成功
    ");
     
        return 1;
    }
     
    /* 11.向单链表的末尾添加一个元素 */
    int insertLastList(Node **pNode,elemType insertElem)
    {
        Node *pInsert;
        Node *pHead;
        Node *pTmp; //定义一个临时链表用来存放第一个节点
     
        pHead = *pNode;
        pTmp = 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 = pTmp;
        printf("insertLastList函数执行,向表尾插入元素成功
    ");
     
        return 1;
    }
     
    /* 12.向单链表中第pos个结点位置插入元素为x的结点,若插入成功返回1,否则返回0 */
     
     
    /* 13.向有序单链表中插入元素x结点,使得插入后仍然有序 */
    /* 14.从单链表中删除表头结点,并把该结点的值返回,若删除失败则停止程序运行 */
    /* 15.从单链表中删除表尾结点并返回它的值,若删除失败则停止程序运行 */
    /* 16.从单链表中删除第pos个结点并返回它的值,若删除失败则停止程序运行 */
    /* 17.从单链表中删除值为x的第一个结点,若删除成功则返回1,否则返回0 */
    /* 18.交换2个元素的位置 */
    /* 19.将线性表进行快速排序 */
     
    /******************************************************************/
    int main()
    {
        Node *pList=NULL;
        int length = 0;
     
        elemType posElem;
     
        initList(&pList);       //链表初始化
        printList(pList);       //遍历链表,打印链表
     
        pList=creatList(pList); //创建链表
        printList(pList);
         
        sizeList(pList);        //链表的长度
        printList(pList);
     
        isEmptyList(pList);     //判断链表是否为空链表
         
        posElem = getElement(pList,3);  //获取第三个元素,如果元素不足3个,则返回0
        printf("getElement函数执行,位置 3 中的元素为 %d
    ",posElem);   
        printList(pList);
     
        getElemAddr(pList,5);   //获得元素5的地址
     
        modifyElem(pList,4,1);  //将链表中位置4上的元素修改为1
        printList(pList);
     
        insertHeadList(&pList,5);   //表头插入元素12
        printList(pList);
     
        insertLastList(&pList,10);  //表尾插入元素10
        printList(pList);
     
        clearList(pList);       //清空链表
        system("pause");
         
    }

    2.

    #define    _CRT_SECURE_NO_WAR
    #include <stdio.h>
    #include<stdlib.h>
    #define ERROR 0
    #define OK    1
    typedef int status;
    typedef int ElemType;
    typedef struct Node
    {
        ElemType data;
        struct Node *next;
    } LNode, *LinkList;
    
    void Build(LinkList L)//建立一个带头结点的单链表
    {
        int n;
        LinkList p, q;
        p = L;
        printf("请输入n和n个数据元素:
    ");
        scanf("%d", &n);
        while (n--)
        {
            q = (LinkList)malloc(sizeof(LNode));
            scanf("%d", &q->data);
            q->next = NULL;
            p->next = q;
            p = q;
        }
    }
    void Print(LinkList L)//计算单链表的长度,然后输出单链表
    {
        int num = 0;
        LinkList p;
        p = L->next;
        while (p)
        {
            num++;
            printf("%d ", p->data);
            p = p->next;
        }
        printf("
    长度为%d:
    ", num);
    }
    void Tips()
    {
        printf("按数字键选择相应操作
    ");
        printf("<1> 输出单链表及其长度:
    ");
        printf("<2> 查找值为x的直接前驱结点:
    ");
        printf("<3> 删除值为x的结点:
    ");
        printf("<4> 将表中元素逆置:
    ");
        printf("<5> 删除表中所有值大于mink且小于maxk的元素:
    ");
        printf("<6> 删除表中所有值相同的多余元素:
    ");
        printf("<7> 分解成两个链表:
    ");
        printf("<8> 在升序链表插入值为X的结点,使仍然有序:
    ");
        printf("<9> 按升序排列:
    ");
        printf("<0> 退出:
    ");
    }
    void Find(LinkList L, int x)//查找值为x的直接前驱结点q
    {
        LinkList p;
        p = L;
        while (p->next &&p->next->data != x)
            p = p->next;
        if (p->next)
            printf("%d的前驱结点为:%d
    
    ", x, p->data);
        else
            printf("没找到!!
    
    ");
    }
    void Delete(LinkList L, int x)//删除值为x的结点
    {
        LinkList p, q;
        p = L;
        while (p->next &&p->next->data != x)
            p = p->next;
        if (p->next)
        {
            q = p->next;
            p->next = q->next;
            free(q);
            printf("删除成功!!
    
    ");
        }
        else
            printf("链表中没有%d
    
    ", x);
    }
    void NiZhi(LinkList L)//把单向链表中元素逆置,类似于头插法建立链表!
    {
        LinkList p, s;
        p = s = L->next;
        L->next = NULL;
        while (p)
        {
            s = s->next;
            p->next = L->next;
            L->next = p;
            p = s;
        }
        printf("逆置成功!!!
    
    ");
    }
    
    
    
    void Delete1(LinkList L)//删除表中所有值大于mink且小于maxk的元素
    {
        int maxk, mink;
        LinkList p, q, s;
        printf("请输入mink,maxk:
    ");
        scanf("%d %d", &mink, &maxk);
        p = L;
        while (p->next && p->next->data <= mink)
            p = p->next;
        s = p->next;
        while (s && s->data<maxk)
        {
            q = s;
            s = s->next;
            free(q);
        }
        p->next = s;
        printf("删除成功
    
    ");
    }
    void Delete2(LinkList L)//删除表中所有值相同的多余元素(使得操作后的线性表中所有元素的值均不相同),
    {
        LinkList p, q, s;
        p = L;
        q = L->next;
        while (q->next)
        {
            if (q->data == q->next->data)
            {
                p->next = q->next;
                s = q;
                q = q->next;
                free(s);
            }
            else
            {
                p = p->next;
                q = q->next;
            }
    
        }
        printf("删除成功!!!!
    ");
    }
    void fenjie(LinkList L)//利用(1)建立的链表,实现将其分解成两个链表,其中一个全部为奇数,另一个全部为偶数
    {
        LinkList s, p, Lb, cur1, cur2;
        Lb = (LinkList)malloc(sizeof(LNode));
        Lb->next = NULL;
        s = L->next;
        L->next = NULL;
        cur1 = L;
        cur2 = Lb;
        while (s)
        {
            p = s;
            s = s->next;
            p->next = NULL;
            if (p->data & 1)
            {
                cur1->next = p;
                cur1 = cur1->next;
            }
            else
            {
                cur2->next = p;
                cur2 = cur2->next;
            }
        }
        cur1 = L->next;
        cur2 = Lb->next;
        printf("元素为奇数的链表:
    ");
        while (cur1)
        {
            printf("%d ", cur1->data);
            cur1 = cur1->next;
        }
        printf("
    元素为偶数的链表:
    ");
        while (cur2)
        {
            printf("%d ", cur2->data);
            cur2 = cur2->next;
        }
        printf("
    
    ");
    }
    void Insert(LinkList L, LinkList p)//在升序链表插入值为X的结点,使仍然有序
    {
        LinkList s;
        s = L;
        while (s->next && s->next->data < p->data)
            s = s->next;
        p->next = s->next;
        s->next = p;
    }
    
    status Sort(LinkList L)//按升序排列
    {
        LinkList s, r;
        s = L->next;
        L->next = NULL;
        while (s)
        {
            r = s;
            s = s->next;
            r->next = NULL;
            Insert(L, r);
        }
        return OK;
    }
    int main()
    {
        int op, x, flag;
        LinkList L, p;
        L = (LinkList)malloc(sizeof(LNode));
        L->next = NULL;
        L->data = -1;
        Build(L);
        Tips();
        scanf("%d", &op);
        while (op)
        {
            switch (op)
            {
            case 1:
                Print(L);
                break;
            case 2:
                printf("请输入要查找的元素X:
    ");
                scanf("%d", &x);
                Find(L, x);
                break;
            case 3:
                printf("请输入要查找的删除X:
    ");
                scanf("%d", &x);
                Delete(L, x);
                break;
            case 4:
                NiZhi(L);
                break;
            case 5:
                Delete1(L);
                break;
            case 6:
                Delete2(L);
                break;
            case 7:
                fenjie(L);
                break;
            case 8:
                printf("请输入要插入的元素X:
    ");
                scanf("%d", &x);
                p = (LinkList)malloc(sizeof(LNode));
                p->data = x;
                Insert(L, p);
                printf("插入成功!!!
    
    ");
                break;
            case 9:
                flag = Sort(L);
                if (flag)
                    printf("排序成功!!
    ");
                break;
            }
            Tips();
            scanf("%d", &op);
        }
        return 0;
    }
  • 相关阅读:
    奇数阶魔方问题
    《DSP using MATLAB》示例9.3
    《DSP using MATLAB》示例9.2
    《DSP using MATLAB》示例9.1
    找个目标很重要
    《DSP using MATLAB》示例Example 8.30
    《DSP using MATLAB》示例Example 8.29
    《DSP using MATLAB》示例Example 8.28
    《DSP using MATLAB》示例Example 8.27
    《DSP using MATLAB》示例Example 8.26
  • 原文地址:https://www.cnblogs.com/sjxbg/p/6038450.html
Copyright © 2020-2023  润新知