list的常见操作以及算法的时间复杂度

list_op.h

/*************************************************************************
        > File Name: list_op.h
        > Author: zhoulin
        > Mail: [email protected]
        > Created Time: Sat 23 Apr 2016 09:23:40 AM CST
 ************************************************************************/

#ifndef _LIST_OP_H
typedef struct _listNode
{
    int v;
    struct _listNode *next;
}listNode;
#define rebuild(p,h,t)  \
{                           if(h == NULL)           {                           h = t = p;          }else{                      t->next = p;            t = p;              }                       t->next = NULL;     }
//打印链表,时间复杂度O(n)
void listPrt(listNode *p);
//链表初始化,时间负责度O(n)
listNode *listInit(listNode *a,int n);
//删除链表P中有过重复的元素
listNode *listDRepeat(listNode *p);
//删除链表中重复元素
listNode *listNRepeat(listNode *p);
//给定一个值,要求链表左边小于该值,链表右边大于该值,且链表的相对位置不改变
listNode *listQuick(listNode *p,int v);
#define _LIST_OP_H
#endif

list_op.c:

/*************************************************************************
        > File Name: list_op.c
        > Author: zhoulin
        > Mail: [email protected]
        > Created Time: Sat 23 Apr 2016 09:15:55 AM CST
 ************************************************************************/
#include "list_op.h"
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#define listSize 14
listNode *listQuick(listNode *p,int v)
{
    fprintf(stdout,"**************************v=%d,大于v的节点在v节点右侧,否则在左侧*****************************\n",v);
    listNode *b_h,*b_t;
    listNode *s_h,*s_t;
    listNode *r_h,*r_t;
    b_h = b_t = s_h =NULL;
    s_t = r_h = r_t =NULL;
    while(p != NULL)
    {
        listNode *pnext = p->next;
        if(p->v == v)
        {
            rebuild(p,r_h,r_t);
        }
        else if(p->v > v)
        {
            rebuild(p,b_h,b_t);
        }else{
            rebuild(p,s_h,s_t);
        }
        p = pnext;
    }
    if(s_t != NULL)
        s_t->next = r_h;
    if(r_t != NULL)
        r_t->next = b_h;
    return s_h;
}
listNode *listNRepeat(listNode *p)
{
    fprintf(stdout,"**************************删除链表重复元素*****************************\n");
    listNode *cur = p;
    int flag[listSize];
    memset((int *)&flag,-1,sizeof(int)*listSize);
    while(cur != NULL)
    {
        flag[cur->v] = 0;
        listNode *pnext = cur->next;
        if(pnext != NULL && flag[pnext->v] == 0)
        {
            cur->next = pnext->next;
        }else
        {
            cur = pnext;
        }
    }
    return p;
}
listNode *listDRepeat(listNode *p)
{
    fprintf(stdout,"*************************删除链表有重复元素*****************************\n");
    int flag[listSize];
    int i = 0;
    memset(&flag,-1,listSize*sizeof(int));
    listNode *rp = p;
    listNode *head,*tail;
    head = tail = NULL;
    while(p != NULL)
    {
        if(flag[p->v] < 0)
        {
            flag[p->v] = 0;
        }
        listNode *pnext = p->next;
        if(pnext != NULL){
            if(flag[pnext->v] == 0)
            {
                ++flag[pnext->v];
            }
        }
        p = pnext;
    }
    while(rp != NULL)
    {
        listNode *next = rp->next;
        if(flag[rp->v] == 0)
        {
            rebuild(rp,head,tail);
        }
        rp = next;
    }
    return head;
}
listNode *listInit(listNode *a,int n)
{
    if(n <= 0)
    {
        return NULL;
    }
    if(n > listSize)
    {
        n = listSize;
    }
    int i = 0;
    fprintf(stdout,"**************************原始链表*****************************\n");
    for(i = 0;i < n;i++)
    {
        a[i].v = rand()%10;
        listNode *cur = &a[i];
        if(i == listSize -1){
            a[i].next = NULL;
            fprintf(stdout,"%d\n",cur->v);
            break;
        }
        a[i].next = &a[i+1];
        fprintf(stdout,"%d ->",cur->v);
    }
    fprintf(stdout,"\n");
    return a;
}
void listPrt(listNode *p)
{
    listNode *cur = p;
    while(cur != NULL)
    {
        if(cur->next == NULL)
        {
            fprintf(stdout,"%d\n\n",cur->v);
            break;
        }
        fprintf(stdout,"%d ->",cur->v);
        cur = cur->next;
    }
}
int main(void)
{
    listNode a[listSize];
    listNode *tmp = NULL;
    listNode *ai = listInit(&a[0],19);
    tmp = listQuick(ai,rand()%10);
    listPrt(tmp);
    ai = listInit(&a[0],19);
    tmp = listNRepeat(ai);
    listPrt(tmp);
    ai = listInit(&a[0],19);
    tmp = listDRepeat(ai);
    listPrt(tmp);
    return 0;
}

测试结果:

**************************原始链表*****************************
3 ->6 ->7 ->5 ->3 ->5 ->6 ->2 ->9 ->1 ->2 ->7 ->0 ->9

**************************v=3,大于v的节点在v节点右侧,否则在左侧*****************************
2 ->1 ->2 ->0 ->3 ->3 ->6 ->7 ->5 ->5 ->6 ->9 ->7 ->9

**************************原始链表*****************************
6 ->0 ->6 ->2 ->6 ->1 ->8 ->7 ->9 ->2 ->0 ->2 ->3 ->7

**************************删除链表重复元素*****************************
6 ->0 ->2 ->1 ->8 ->7 ->9 ->3

**************************原始链表*****************************
5 ->9 ->2 ->2 ->8 ->9 ->7 ->3 ->6 ->1 ->2 ->9 ->3 ->1

*************************删除链表有重复元素*****************************
5 ->8 ->7 ->6
时间: 2024-12-11 16:41:10

list的常见操作以及算法的时间复杂度的相关文章

常见算法的时间复杂度(大O计数法)

定义 ? 对于不同的机器环境而言,确切的单位时间是不同的,但是对于算法进行多少个基本操作(即花费多少时间单位)在规模数量级上却是相同的,由此可以忽略机器环境的影响而客观的反应算法的时间效率. 对于算法的时间复杂度效率,我们可以用"大O记法"来表示. "大O记法":对于单调的整数函数f,如果存在一个整数函数g和实常数c>0,使得对于充分大的n总有f(n)<=c*g(n),就说函数g是f的一个渐近函数(忽略常数),记为f(n)=O(g(n)).也就是说,在趋

常见排序算法以及时间复杂度

一.冒泡排序: public static void bubbleSort(int []arr) { for(int i =1;i<arr.length;i++) { for(int j=0;j<arr.length-i;j++) { if(arr[j]>arr[j+1]) { int temp = arr[j]; arr[j]=arr[j+1]; arr[j+1]=temp; } } } } 冒泡排序最好的情况是一趟就排完  时间复杂度为O(n); 最坏的情况就是刚好是反序的 需要循环

常见数据结构与算法整理总结(上)

数据结构是以某种形式将数据组织在一起的集合,它不仅存储数据,还支持访问和处理数据的操作.算法是为求解一个问题需要遵循的.被清楚指定的简单指令的集合.下面是自己整理的常用数据结构与算法相关内容,如有错误,欢迎指出. 为了便于描述,文中涉及到的代码部分都是用Java语言编写的,其实Java本身对常见的几种数据结构,线性表.栈.队列等都提供了较好的实现,就是我们经常用到的Java集合框架,有需要的可以阅读这篇文章.Java - 集合框架完全解析 一.线性表 1.数组实现 2.链表 二.栈与队列 三.树

第5课 算法的时间复杂度

1. 定性判断算法的效率 (1)时间复杂度:算法运行后对时间需求量的定性描述(数据结构课程集中讨论的内容) (2)空间复杂度:算法运行后对空间需求量的定性描述(判断方法类似于时间复杂度) 2. 大O表示法 (1)算法效率严重依赖于操作(Operation)数量 (2)操作数量的估算可以作为时间复杂度的估算 (3)在判断时首先关注操作数量的最高次项 O(5) =O(1) O(2n+1)=O(2n)=O(n) O(n2+n+1) = O(n2) O(3n3+1)=O(3n3)=O(n3) 3. 常见

动态单链表的传统存储方式和10种常见操作-C语言实现

顺序线性表的优点:方便存取(随机的),特点是物理位置和逻辑为主都是连续的(相邻).但是也有不足,比如:前面的插入和删除算法,需要移动大量元素,浪费时间,那么链式线性表 (简称链表) 就能解决这个问题. 一般链表的存储方法 一组物理位置任意的存储单元来存放线性表的数据元素,当然物理位置可以连续,也可以不连续,或者离散的分配到内存中的任意位置上都是可以的.故链表的逻辑顺序和物理顺序不一定一样. 因为,链表的逻辑关系和物理关系没有必然联系,那么表示数据元素之间的逻辑映象就要使用指针,每一个存储数据元素

算法的时间复杂度和空间复杂度合称为算法的复杂度

算法的时间复杂度和空间复杂度合称为算法的复杂度. 1.时间复杂度 (1)时间频度 一个算法执行所耗费的时间,从理论上是不能算出来的,必须上机运行测试才能知道.但我们不可能也没有必要对每个算法都上机测试,只需知道哪个算法花费的时间多,哪个算法花费的时间少就可以了.并且一个算法花费的时间与算法中语句的执行次数成正比例,哪个算法中语句执行次数多,它花费时间就多.一个算法中的语句执行次数称为语句频度或时间频度.记为T(n). (2)时间复杂度 在刚才提到的时间频度中,n称为问题的规模,当n不断变化时,时

常见数据结构与算法整理总结

转载:http://www.jianshu.com/p/42f81846c0fb?hmsr=toutiao.io&utm_medium=toutiao.io&utm_source=toutiao.io 一.概述 以前看到这样一句话,语言只是工具,算法才是程序设计的灵魂.的确,算法在计算机科学中的地位真的很重要,在很多大公司的笔试面试中,算法掌握程度的考察都占据了很大一部分.不管是为了面试还是自身编程能力的提升,花时间去研究常见的算法还是很有必要的.下面是自己对于算法这部分的学习总结. 算法

常见的排序算法

描述: 排序算法可谓数据结构模块中的重中之重,常见的哈希表,二叉树,搜索树/平衡树,位图等数据结构只是处理实际问题的抽象方法,实际在处理接受或生成的数据集时,排序算法显得尤其重要,排序算法家族很庞大,其中包括了冒泡排序,选择排序,插入排序,堆排序,快速排序,归并排序,基数排序,计数排序,希尔排序,箱排序,树型排序等众多算法,每种排序都有各自的特性,没有好坏之分,只有在特定的场景使用合适的排序算法才是上策,单纯的来比显得太过绝对,没有可比性.因为实际需求及各方面条件的限制使得排序算法的可选范围往往

十种常见的排序算法,面试算法必考

1.冒泡排序 已知一组无序数据a[1].a[2].……a[n],需将其按升序排列.首先比较a[1]与a[2]的值,若a[1]大于a[2]则交换两者的值,否则不变.再比较a[2]与a[3]的值,若a[2]大于a[3]则交换两者的值,否则不变.再比较a[3]与a[4],以此类推,最后比较a[n-1]与a[n]的值.这样处理一轮后,a[n]的值一定是这组数据中最大的.再对a[1]~a[n-1]以相同方法处理一轮,则a[n-1]的值一定是a[1]~a[n-1]中最大的.再对a[1]~a[n-2]以相同方