链表的时间复杂度如何

时间:2019-02-11 22:14:48

标签: algorithm big-o

使用for循环的链表的运行时复杂度是多少?根据我的理解,它是0(n)。我不确定我的答案是否正确。

import java.util.LinkedList;
import java.util.List;

public class Test1 {

	public static void main(String[] argv) {
		List<Integer> r;

		// Displays entire sequence for 1 child
		System.out.println("Sequence for 1 child");
		System.out.println(r = func1(1, 2, 1));
		// Displays the last person
		System.out.printf("The Winner is %d \n", r.get(r.size() - 1));
		System.out.println("----------------------------------------");

		// Displays entire sequence for 2 children
		System.out.println("Sequence for 2 children");
		System.out.println(r = func1(2, 2, 1));
		// Displays the last person
		System.out.printf("The Winner is %d \n", r.get(r.size() - 1));
		System.out.println("----------------------------------------");

		// Displays entire sequence for 3 children
		System.out.println("Sequence for 3 children");
		System.out.println(r = func1(3, 2, 1));
		// Displays the last person
		System.out.printf("The Winner is %d \n", r.get(r.size() - 1));
		System.out.println("----------------------------------------");

		// Displays entire sequence for 4 children
		System.out.println("Sequence for 4 children");
		System.out.println(r = func1(4, 2, 1));
		// Displays the last person
		System.out.printf("The Winner is %d \n", r.get(r.size() - 1));
		System.out.println("----------------------------------------");

		// Displays entire sequence for 5 children
		System.out.println("Sequence for 5 children");
		System.out.println(r = func1(5, 2, 1));
		// Displays the last person
		System.out.printf("The Winner is %d \n", r.get(r.size() - 1));
		System.out.println("----------------------------------------");

		// Displays entire sequence for 6 children
		System.out.println("Sequence for 6 children");
		System.out.println(r = func1(6, 2, 1));
		// Displays the last person
		System.out.printf("The Winner is %d \n", r.get(r.size() - 1));
		System.out.println("----------------------------------------");

		// Displays entire sequence for 7 children
		System.out.println("Sequence for 7 children");
		System.out.println(r = func1(7, 2, 1));
		// Displays the last person
		System.out.printf("The Winner is %d \n", r.get(r.size() - 1));
		System.out.println("----------------------------------------");

		// Displays entire sequence for 8 children
		System.out.println("Sequence for 8 children");
		System.out.println(r = func1(8, 2, 1));
		// Displays the last person
		System.out.printf("The Winner is %d \n", r.get(r.size() - 1));
		System.out.println("----------------------------------------");

	}

	// Remove N elements in equal steps starting at specific point
	public static List<Integer> func1(int N, int step, int start) {
		if (N < 1 || step < 1 || start < 1) {
			return null;
		}

		List<Integer> p = new LinkedList<Integer>();
		for (int i = 0; i < N; i++) {
			p.add(i + 1);

		}

		List<Integer> r = new LinkedList<Integer>();
		int i = (start - 2) % N;
		for (int j = N; j > 0; j--) {
			i = (i + step) % N--;
			r.add(p.remove(i--));
			// System.out.println(r);
		}

		return r;
	}

}

输出如下 1个孩子的顺序 [1]

获胜者为1

2个孩子的顺序 [2,1]

获胜者为1

3个孩子的顺序 [2,1,3]

获胜者是3

4个孩子的顺序 [2,4,3,1]

获胜者为1

5个孩子的顺序 [2,4,1,5,3]

获胜者是3

6个孩子的顺序 [2,4,6,3,1,5]

获胜者是5

7个孩子的顺序 [2,4,6,1,5,3,7]

获胜者是7

8个孩子的顺序 [2,4,6,8,3,7,5,1]

获胜者为1

1 个答案:

答案 0 :(得分:2)

TL; DR:

您的第一个循环是O(N),第二个循环是O(N^2)

(不是)详细说明:

您的第一个循环是O(N),因为您正在访问列表中的所有元素,并且每个add调用都是O(1)

摘自Java的官方文档:

  

布尔布尔add(E e)   将指定的元素追加到此列表的末尾。   此方法等效于addLast(E)

如果必须使用add(int index, E e),则将是O(N^2),因为具有2个参数的此函数的访问时间复杂度为O(N),而访问N的时间为O(N)函数为您提供O(N^2)。但是,这不是您的情况。

另一方面,您的第二个循环是O(N^2),因为您要添加带有O(1)的元素,但同时也要使用delete(int index)删除元素,而该元素需要O(N) 。该方法使用O(N),因为首先,它在要访问的位置搜索节点,然后删除更改指针引用的元素。请记住,LinkedList没有直接访问权限,它具有指针,O(1)仅适用于涉及头和尾元素或使用迭代器的操作。