zoukankan      html  css  js  c++  java
  • C语言中的链表

    参考自:http://data.biancheng.net/view/5.html

    如何创建链表

    首先创建一个结构体表示节点:

    typedef struct Link{
        int  elem;
        struct Link *next;
    }link;

    接下来编写初始化函数。由一维数组初始化链表。

    link * initLink(int *num,int length){
        link * p=(link*)malloc(sizeof(link));//创建一个头结点
        link * temp=p;//声明一个指针指向头结点,用于遍历链表
        //生成链表
        for (int i=0; i<length; i++) {
            link *a=(link*)malloc(sizeof(link));
            a->elem=num[i];
            a->next=NULL;
            temp->next=a;
            temp=temp->next;
        }
        return p;
    }

    在每次循环中,首先将值赋给当前节点,将当前节点的指针指向NULL,然后移动一位,到下一个节点。依次赋值,直到完成,于是最后一个节点的next域保持NULL。

    插入小tip:通过传递数组名或数组指针参数到子函数中,以获得数组长度是不可行的。因为num是函数参数,到了本函数中,只是一个指针(地址,系统在本函数运行时,是不知道其所表示的地址有多大的数据存储空间,这里只是告诉函数一个数据存储空间首地址)。

    而在数组定义所在的代码区中就可以使用以下方法获取数组大小。

    double num[] = {1,2,3,4};
    int length;
    length=sizeof(num)/sizeof(num[0]);

    接下来定义遍历所有元素输出链接的函数。只要temp指针指向的结点的next不是Null,就执行输出语句,否则跳出循环。

    void display(link *p){
        link* temp=p;//将temp指针重新指向头结点
        while (temp->next) {
            temp=temp->next;
            printf("%d -> ",temp->elem);
        }
        printf("NULL
    ");
    }

    测试如下:

    int main() {
        int a[6] = {10,5,3,2,1,6};
        link *p=initLink(a,6);
        display(p);
    
        return 0;
    }

    如何插入新节点

    链表插入的函数,p是链表,elem是插入的结点的数据域,add是插入的位置。

    link * insertElem(link * p,int elem,int add){
        link * temp=p;//创建临时结点temp
        //首先找到要插入位置的上一个结点
        for (int i=1; i<add; i++) {
            if (temp==NULL) {
                printf("插入位置无效
    ");
                return p;
            }
            temp=temp->next;
        }
        //创建插入结点c
        link * c=(link*)malloc(sizeof(link));
        c->elem=elem;
        //向链表中插入结点
        c->next=temp->next;
        temp->next=c;
        return  p;
    }

    如何移除节点

    删除结点的函数,p代表操作链表,add代表删除节点的位置。

    link * delElem(link * p,int add){
        link * temp=p;
        //遍历到被删除结点的上一个结点
        for (int i=1; i<add; i++) {
            temp=temp->next;
        }
        link * del=temp->next;//单独设置一个指针指向被删除结点,以防丢失
        temp->next=temp->next->next;//删除某个结点的方法就是更改前一个结点的指针域
        free(del);//手动释放该结点,防止内存泄漏
        return p;
    }

    查找节点元素

    查找结点的函数,elem为目标结点的数据域的值,返回找到的位置。

    int selectElem(link * p,int elem){
        link * temp=p;
        int i=1;
        while (temp->next) {
            temp=temp->next;
            if (temp->elem==elem) {
                return i;
            }
            i++;
        }
        return -1;
    }

    测试:

    int main() {
        int a[6] = {10,5,3,2,1,6};
        link *p=initLink(a,6);
        display(p);
    
        printf("在第4的位置插入元素5:
    ");
        p=insertElem(p, 5, 4);
        display(p);
    
        printf("删除第2位置的元素:
    ");
        p=delElem(p, 2);
        display(p);
    
        printf("查找元素2的位置为:
    ");
        int address=selectElem(p, 2);
        if (address==-1) {
            printf("没有该元素
    ");
        }else{
            printf("元素2的位置为:%d
    ",address);
        }
        return 0;
    }

  • 相关阅读:
    MyBatis 学习笔记
    JavaEE路径陷阱之getRealPath
    Java路径问题最终解决方案—可定位所有资源的相对路径寻址
    Hibernate4.3.10通过slf4j使用log4j
    Hibernate关联关系映射
    SpringMVC 学习笔记
    Spring 学习笔记
    Hibernate 学习笔记
    Struts2 学习笔记
    vue element tree组件,根据不同的状态显示不同的字体颜色
  • 原文地址:https://www.cnblogs.com/dingdangsunny/p/15221760.html
Copyright © 2011-2022 走看看