美文网首页
数据结构和算法

数据结构和算法

作者: Coder_JdHo | 来源:发表于2020-12-14 11:28 被阅读0次

    堆和栈

    数据结构中的堆栈:
    堆:树状结构,是一种优先队列,先进先出
    栈:桶状结构,先进后出

    操作系统中的堆栈:
    都是指内存空间

    1. 申请方式
      堆是由程序员自己申请并指明大小,在c中malloc函数 如p1 = (char *)malloc(10);
      栈由系统自动分配,如声明在函数中一个局部变量 int b; 系统自动在栈中为b开辟空间
    2. 申请后系统的响应
      栈:只要栈的剩余空间大于所申请空间,系统将为程序提供内存,否则将报异常提示栈溢出。
      堆:首先应该知道操作系统有一个记录空闲内存地址的链表,当系统收到程序的申请时,会 遍历该链表,寻找第一个空间大于所申请空间的堆结点,然后将该结点从空闲结点链表中删除,并将该结点的空间分配给程序,另外,对于大多数系统,会在这块内 存空间中的首地址处记录本次分配的大小,这样,代码中的delete语句才能正确的释放本内存空间。另外,由于找到的堆结点的大小不一定正好等于申请的大 小,系统会自动的将多余的那部分重新放入空闲链表中。
    3. 申请大小的限制
      栈:在Windows下,栈是向低地址扩展的数据结 构,是一块连续的内存的区域。这句话的意思是栈顶的地址和栈的最大容量是系统预先规定好的,在WINDOWS下,栈的大小是2M(也有的说是1M,总之是 一个编译时就确定的常数),如果申请的空间超过栈的剩余空间时,将提示overflow。因此,能从栈获得的空间较小。
      堆:堆是向高地址扩展的数据结构,是不连续的内存区域。这是由于系统是用链表来存储的空闲内存地址的,自然是不连续的,而链表的遍历方向是由低地址向高地址。堆的大小受限于计算机系统中有效的虚拟内存。由此可见,堆获得的空间比较灵活,也比较大。
    4. 申请效率的比较:
      栈由系统自动分配,速度较快。但程序员是无法控制的。
      堆是由new分配的内存,一般速度比较慢,而且容易产生内存碎片,不过用起来最方便.

    进程线程与栈、堆的关系

    一般一个进程有一个运行时堆(heap),【动态大小】,这个堆为本进程中所有线程共享;线程拥有各自独立的(/私有的)栈(stack),大小一般是1M/2M(不同系统不一样)【固定大小】

    1.栈区(stack):由系统的编译器自动的释放,主要用来存放方法中的参数,一些临时的局部变量等,并且方法中的参数一般在操作完后,会由编译器自动的释放掉。

    2.堆区(heap):由程序员决定,在Java中,如果程序员不释放的话,一般会由垃圾回收机制自动的清理掉。此区域主要用来存放我们经常创建的对象、动态的申请的临时空间等。

    3.数据区(data seg):也称全局区或者静态区,根据名称我们就应该知道用来存放一些全局的东西,比如我们经常用到的静态变量、全局变量等都会存放到数据区,此区域上的东西都被全局所共享。比如我们可以采取类名.的方式就可以访问到方法,这就是所谓的静态方法,存放到数据区的。

    4.代码区:存放程序编译后可以执行代码的地方。比如执行代码时写的While语句、if条件语句等,都会存放到此。

    进程间堆不能相互访问

    保护模式下进程的内存空间是分离的,进程分配的堆只能进程内访问
    不过16位实模式下(纯DOS),全局只有一个地址空间,进程之间可以相互窃取对方信息

    如果用new和malloc分配的堆空间在不同进程中是不可以共享的
    不过用globalAlloc申请的内存可以在进程中共享,比如剪切板就是用的他们

    堆的大小:堆的大小实际上(运行时)动态变化的,但有理论最大值,(取决于内存或虚拟内存?)

    链表倒序

    void reverse(list_node *head)
    {
        if(NULL == head || NULL == head->next )
        {
            return;
        }
        
        list_node pre = head;
        list_node c = head->next;
        list_node n = NULL;
        
        while (NULL != c)
        {
            n = c.next;
            c.next = pre;
            pre = c;
            c = n;
        }
        
        head.next = NULL;
        
        return pre;
    }
    

    冒泡排序

    //(从小到大)
    void bubbleSort(int a[], int n)
    {
        if (n < 2) {
            return;
        }
        
        int temp;
        
        for (int i = 0; i < n - 1; i++) {
            for (int j = 0; j < n - i - 1; j++) {
                if (a[j] > a[j + 1]) {
                    temp = a[j];
                    a[j] = a[j + 1];
                    a[j + 1] = temp;
                }
            }
        }
    }
    

    选择排序

    //(从小到大)
    void selectSort(int *a, int n)
    {
        if (n < 2) {
            return;
        }
        
        int temp;
        
        for (int i = 0; i < n - 1; i++) {
            for (int j = i + 1; j < n; j++) {
                if (a[i] > a[j]) {
                    temp = a[i];
                    a[i] = a[j];
                    a[j] = temp;
                }
            }
        }
    }
    

    插入排序

    //(从小到大)
    void insertSort(int *a, int n)
    {
        if (n < 2) {
            return;
        }
        
        int i, j, temp;
        
        for (i = 1; i < n; i++) {
            
            temp = a[i];
            j = i - 1;
            
            while (j >= 0 && temp < a[j]) {
                a[j + 1] = a[j];
                j--;
            }
            
            a[j + 1] = temp;
        }
    }
    

    快速排序

    基本思想:通过一趟排序将待排记录分隔成独立的两部分,其中一部分记录的关键字均比另一部分的关键字小,则可分别对这两部分记录继续进行排序,递归调用,以达到整个序列有序。

    void quickSort(int a[], int left, int right)
    {
        if (left >= right) {
            return;
        }
        
        int i = left, j = right, key = a[left], temp = 0;
        
        while (i < j) {
            while (i < j && a[j] >= key) {
                j--;
            }
            
            while (i < j && a[i] <= key) {
                i++;
            }
            
            if (i < j) {
                temp = a[i];
                a[i] = a[j];
                a[j] = temp;
            }
        }
        
        a[left] = a[i];
        a[i] = key;
        
        quickSort(a, left, i - 1);
        quickSort(a, i + 1, right);
    }
    

    字符串排序

    void stringSort()
    {
        NSString *string = @"kassf骄傲覅微积分违法IQ多看看我经济法基督教扩大加肥加大djfoeIJOFIJODSJIFOI13243423";
        NSLog(@"%@", string);
        
        NSMutableArray *array = [NSMutableArray array];
        for (int i = 0; i < string.length; i++) {
            [array addObject:[string substringWithRange:NSMakeRange(i, 1)]];
        }
        
        //NSLog(@"%@", array);
        
        [array sortUsingComparator:^NSComparisonResult(id  _Nonnull obj1, id  _Nonnull obj2) {
            NSString *string1 = (NSString *)obj1;
            NSString *string2 = (NSString *)obj2;
            NSInteger ascll1 = [string1 characterAtIndex:0];
            NSInteger ascll2 = [string2 characterAtIndex:0];
    
            //return [string1 compare:string2 options:NSBackwardsSearch];
            //return [string1 compare:string2];
    
            if (ascll1 > ascll2) {
                return NSOrderedDescending;
            }
            else if (ascll1 == ascll2) {
                return NSOrderedSame;
            }
            else {
                return NSOrderedAscending;
            }
        }];
        
    //    NSInteger count = array.count;
    //    for (NSInteger i = 0; i < count; i++) {
    //        for (NSInteger j = 0; j < count - 1 - i; j++) {
    //            NSString *string1 = array[j];
    //            NSString *string2 = array[j+1];
    //            NSInteger character1 = [string1 characterAtIndex:0];
    //            NSInteger character2 = [string2 characterAtIndex:0];
    //            if (character1 > character2) {
    //                [array exchangeObjectAtIndex:j withObjectAtIndex:j + 1];
    //            }
    //        }
    //    }
        
        NSString *newString = [array componentsJoinedByString:[NSString string]];
        
        NSLog(@"newString: %@", newString);
    }
    

    查找最大值和最小值

    //(两两一组比较,3n/2次)
    BOOL search(int a[], int n, int *max, int *min)
    {
        if (n < 1) {
            return NO;
        }
        
        *max = a[0];
        *min = a[0];
        
        //int i = (n % 2 == 0 ? 0 : 1);
        int i = 1;
        
        while (i + 1 < n) {
            if (a[i] > a[i+1]) {
                if (*max < a[i]) {
                    *max = a[i];
                }
                
                if (*min > a[i+1]) {
                    *min = a[i+1];
                }
            }
            else {
                if (*max < a[i+1]) {
                    *max = a[i+1];
                }
                
                if (*min > a[i]) {
                    *min = a[i];
                }
            }
            
            i += 2;
        }
        
        //最后一个数如果没比较的话,单独比较
        if (i < n) {
            int last = a[n - 1];
            if (*max < last) {
                *max = last;
            }
            else if (*min > last) {
                *min = last;
            }
        }
        
        return YES;
    }
    

    分治法查找

    void divideSearch(int a[], int left, int right, int *max, int *min)
    {
        if (left > right) {
            return;
        }
        
        if (right - left > 1) {
            int leftMax, leftMin, rightMax, rightMin;
            int mid = (right + left) / 2;
            
            divideSearch(a, left, mid, &leftMax, &leftMin);
            divideSearch(a, mid + 1, right, &rightMax, &rightMin);
            
            *max = (leftMax > rightMax ? leftMax : rightMax);
            *min = (leftMin < rightMin ? leftMin : rightMin);
            
            return;
        }
        
        if (a[left] > a[right]) {
            *max = a[left];
            *min = a[right];
        }
        else {
            *max = a[right];
            *min = a[left];
        }
    }
    

    二分查找

    //(在有序的数组中查找指定数字的位置)
    int findKeyNum(int *a, int count, int keyNumber)
    {
        int max = count - 1, min = 0, mid;
        
        while (max >= min) {
            mid = (max + min) / 2;
            
            if (keyNumber > a[mid]) {
                min = mid + 1;
            }
            else if (keyNumber < a[mid]) {
                max = mid - 1;
            }
            else {
                return mid + 1; //返回第几个
            }
        }
        
        return -1;
    }
    

    交换两个数

    void exchageNum(int *num1, int *num2)
    {
    //    //加法
    //    *num1 = *num1 + *num2;
    //    *num2 = *num1 - *num2;
    //    *num1 = *num1 - *num2;
        
        //异或(相同为0,不同为1. 可以理解为不进位加法)
        *num1 = *num1 ^ *num2;
        *num2 = *num1 ^ *num2;
        *num1 = *num1 ^ *num2;
    }
    

    最大公约数

    void maxDivisor(unsigned int a, unsigned int b)
    {
        CFAbsoluteTime startTime = CFAbsoluteTimeGetCurrent();
        
        //遍历法
        unsigned int min = MIN(a, b);
        unsigned int maxDivisor = 1;
        for (unsigned int i = min; i > 1; i--) {
            if (a % i == 0 && b % i == 0) {
                maxDivisor = i;
                break;
            }
        }
        
    //    //辗转相除法(欧几里得算法)
    //    uint r, maxDivisor;
    //    while (a % b != 0) {
    //        r = a % b;
    //        a = b;
    //        b = r;
    //    }
    //    maxDivisor = b;
        
        CFAbsoluteTime endTime = CFAbsoluteTimeGetCurrent();
        NSLog(@"TimeCount:%.9f", endTime - startTime);
        
        
        NSLog(@"maxDivisor is %d", maxDivisor);
    }
    

    typedef struct BTNode *Tree;
    
    //二叉树结构体
    struct BTNode {
        int data;
        struct BTNode *left, *right;
    };
    
    //创建二叉树
    Tree creatTree()
    {
        int input;
        scanf("%d", &input);
        
        if (input == 0) {
            return NULL;
        }
        
        Tree node = malloc(sizeof(Tree));
        
        node->data = input;
        node->left = creatTree();
        node->right = creatTree();
        
        return node;
    }
    
    //遍历二叉树
    void traverseTree(Tree node)
    {
        if (node == NULL) {
            return;
        }
        
        printf("%d ", node->data);
        traverseTree(node->left);
        traverseTree(node->right);
    }
    
    void treeTest()
    {
        Tree tree = creatTree();
        
        traverseTree(tree);
        
        free(tree);
    }
    

    相关文章

      网友评论

          本文标题:数据结构和算法

          本文链接:https://www.haomeiwen.com/subject/chneqqtx.html