算法导论10.2链表

带哨兵的双向链表,代码中我使用了nullptr,所以需要编译器升级,我的编译器是gcc/g++ 4.7.0这是可以的,编译的时候加参数—std=c++0x

节点中还可能有卫星元素

/*
 * IA_10.2LinkedLists.cpp
 *
 *  Created on: Feb 12, 2015
 *      Author: sunyj
 */
#include <stdint.h>
#include <iostream>

class ListNode {
public:
    ListNode() : key(0), data(0), prev(nullptr), next(nullptr) { }
    ListNode(int64_t const k, int64_t d) : key(k), data(d), prev(nullptr), next(nullptr) { }

    int64_t key;
    int64_t data;
    ListNode* prev;
    ListNode* next;
};

// LIST-SEARCH(L, k)
// x = L.nil.next
// while ( x != L.nil and x.key != k)
//     x = x.next
// return x

// LIST-INSERT(L, x)
// x.next = L.nil.next
// L.nil.next.prev = x
// L.nil.next = x
// x.prev = L.nil

// LIST-DELETE(L, x)
// x.prev.next = x.next
// x.next.prev = x.prev

class LinkedList {
public:
    LinkedList() : nil(&m_nil)
    {
        nil->prev = nil;
        nil->next = nil;
        nil->data = -1; //
    }
    ListNode* search(int64_t const k)
    {
        ListNode* x = nil->next;
        while (x != nil && k != x->key)
        {
            x = x->next;
        }
        return x;
    }
    void insert(ListNode* x)
    {
        x->next         = nil->next;
        nil->next->prev = x;
        nil->next       = x;
        x->prev         = nil;
    }
    void del(ListNode* x)
    {
        x->prev->next = x->next;
        x->next->prev = x->prev;
    }
    void print()
    {
        ListNode* x = nil->next;
        while (nil != x)
        {
            std::cout << x->key << " ";
            x = x->next;
        }
        std::cout << std::endl;
    }
private:
    ListNode  m_nil; // empty list has noe node, pointer nill points to it.
    ListNode* nil;
};

int main()
{
    LinkedList list;
    ListNode node1(1, 100);
    ListNode node4(4, 400);
    ListNode node16(16, 1600);
    ListNode node9(9, 900);
    list.insert(&node1);
    list.insert(&node4);
    list.insert(&node16);
    list.insert(&node9);
    list.print();
    ListNode node25(25, 2500);
    list.insert(&node25);
    list.print();
    list.del(&node1);
    list.print();
    ListNode* tmp;
    tmp = list.search(9);
    list.del(tmp);
    list.print();
    return 0;
}

时间: 2024-10-06 19:42:51

算法导论10.2链表的相关文章

选择问题&mdash;&mdash;算法导论(10)

1. 引言     这一篇我们来探讨选择问题. 它的提法是: 输入:一个包含n个(互异)数的序列A和一个数i(1≤i≤n). 输出:元素x(x∈A),且A中有i-1个元素比x小. 简单的说,就是在A中找到第i小的数. 2. 期望为线性时间的选择算法 (1) 算法描述与实现     我们先给出算法的伪代码描述: 其主要思想与我们前面介绍的快速排序--算法导论(8)基本一样,只是在该问题中,我们每次递归时,只用考虑第i小的数可能出现的分组. 下面给出Java实现代码: public static v

算法导论10:栈链表的简化、队列的数组实现 2016.1.10

新年的前十天做了比较有意义的事情就是坚持每天写博客,明天就开始期末考试了,所以等假期再继续学习. 把昨天提到的S.bottom简化之后又改了栈的链表.代码如下(已折叠): #include<stdio.h> #include<stdlib.h> typedef struct _node{ int num; struct _node *next; }node; node *s; void build(node *&S) { s=(node *)malloc(sizeof(no

算法导论 10.4 有根树的表示

10.4-2 给定n个结点的二叉树,写出一个O(n)时间的递归程序,将该树种每个结点的关键字输出. 伪代码: 1 TREE-PRINT(T) 2 if T != NIL 3 print key[T] 4 TREE-PRINT( left[T] ) 5 TREE-PRINT( right[T] ) c实现: void TreePrint( Tree T ) { if ( T != NULL ) { PrintElement( T ); TreePrint( T->left ); TreePrint

算法导论 10.2-3

题目:使用单链表实现队列,Enqueue与Dequeue操作时间为O(1) 代码: struct Node; struct QueueRecord; typedef struct Node * PtrToNode; typedef struct QueueRecord * Queue; struct Node { ElementType Element; PtrToNode Next; }; struct QueueRecord { PtrToNode Front; PtrToNode Rear

算法导论 10.2-7

题目:给出O(N)运行时间的非递归算法,实现对一个含N个元素的链表的逆转,要求空间复杂度为O(1) 代码: /* Assuming List with header and L is not empty */ List ReverseList( List L ) { Position CurrentPos, NextPos; NextPos = L->Next; L->Next = NULL; while ( NextPos != NULL ) { CurrentPos = NextPos;

算法导论 10.1-2 用一个数组实现两个栈

一.题目 用一个数组A[ 1....N ]实现两个栈,除非数组的每一个单元都被使用,否则栈例程不能有溢出,注意PUSH和POP操作的时间应为O(1). 二.解法 对于一个数组,由它的两端作为栈底,栈向数组中间扩展.当数组中每个元素被用到时,栈满. 三.代码 struct Node; typedef Node *ComStack; struct Node { int Capacity; int TopL; int TopR; ElementType *Array; }; ComStack Crea

双端队列C实现代码 算法导论10.1-5 10.1-6 10.1-7

数组实现双端队列的时候注意区别判断上溢和下溢. 用两个栈实现队列,就相当于把两个栈底靠在一起(背靠背),一个栈用来出队列,一个栈用来进队列.这个队列的操作时间大部分时候是常数时间,除了出列的栈为空,需要把进列的栈全部转移过去,再出列.Back()操作和Pop()操作类似,也是这样. 而两个队列实现栈,队列轮流充当入栈和出栈的角色,而什么时候会改变角色呢,就是Pop()操作.Pop()操作先把一个队列中的所有元素全部出列并加入另外一个空队列中去,然后再出列(第二个队列). 实现代码为C #incl

算法导论 10.1-7

题目:用两个队列实现一个栈,并分析栈操作运行时间 分析: 栈的操作只能在表头进行:而队列的入队在表头进行,出队只能在栈尾进行: 考虑将栈底元素变为栈顶元素,即进行倒置,就能在表头进行Pop操作: 解答:(不考虑溢出) 1.使用两个队列A与Tmp,Tmp队列作为中转: 2.当进行Push操作时,在队列A中进行入队操作: 3.当进行Pop操作时,使队列A中的元素出队并进队在队列Tmp中,直到队列A为空,则队列实现了倒置,队头元素变为队尾元素,Tmp执行出队操作,在对Tmp实行同样步骤,将元素倒置到队

算法导论之链表

一.概念 (1)数组的线性序是由数组的下标决定的,链表中的顺序是由各对象中的指针所决定的 (2)链表结点结构 node *prev; node *next; int key; (3)链表结点 node *head; node *nil;//哨兵 (4)对链表的操作 LIST-SEARCH(L, k) LIST-INSERT(L, x) LIST-DELETE(L, x) (5)哨兵是个哑对象,可以简化边界条件 二.代码 (1)没有哨兵的情况 [cpp] view plain copy print