定义MyLink
package mylinkedlist;
public interface MyLink{
//返回链表的长度
int size();
//判断链表是否为空
boolean isEmpty();
//默认在链表尾部添加元素
boolean add(E e);
//添加到链表第一个
boolean addFirst(E e);
//删除链表中的某个元素
boolean remove(E o);
//清空链表
void clear();
//在链表的某个位置添加元素
void add(int index, E element);
//删除链表中某个位置的元素
boolean remove(int index);
//返回链表中某个位置的元素
E get(int index);
//将链表中某个位置的元素替换为新元素
boolean set(int index, E element);
//查找链表中的某个元素
int indexOf(Object o);
//返回链表的字符串表示
String toString();
}
实现MyLink
public class MySingleLinkedList implements MyLink{
int size = 0;
private MyNode head;
private MyNode last;
private class MyNode{
E item;
MyNode next;
public MyNode(E element, MyNode next) {
this.item = element;
this.next = next;
}
}
public MySingleLinkedList() {
head = new MyNode<>(null,null);
head.next = last;
}
}
@Override
public int size() {
return size;
}
@Override
public boolean isEmpty() {
return head.next == last;
}
//添加到链表尾部
@Override
public boolean add(Object o) {
MyNode preMyNode = head;
MyNode newNode = new MyNode(o,last);
while (preMyNode.next != last){
preMyNode = preMyNode.next;
}
preMyNode.next = newNode;
size++;
return true;
}
@Override
public boolean addFirst(Object o) {
MyNode nextMyNode = head.next;
MyNode newNode = new MyNode(o,nextMyNode);
head.next = newNode;
size++;
return true;
}
@Override
public boolean remove(Object o) {
MyNode a = head;
MyNode b = a.next;
if(indexOf(o) == -1){
return false;
}else{
for(;b != last;a = a.next){
if(b.item.equals(o)){
break;
}
}
a.next = b.next;
size--;
return true;
}
}
@Override
public void clear() {
head.next = last;
size = 0;
}
//添加到链表的某个位置
@Override
public void add(int index, Object element) {
if (index < 0 || index > size) {
throw new IndexOutOfBoundsException("IndexOutOfBounds!!!! Index: "+index+", Size: "+size);
} else if (index == size-1) {
add(element);
} else if (index ==0) {
addFirst(element);
} else {
MyNode preMyNode = head;
for (int i = 0; i < index; i++) {
preMyNode = preMyNode.next;
}
MyNode nextMyNode = preMyNode.next;
MyNode newNode = new MyNode(element, nextMyNode);
preMyNode.next = newNode;
size++;
}
}
@Override
public boolean remove(int index) {
if (index < 0 || index >= size) {
throw new IndexOutOfBoundsException("IndexOutOfBounds!!!! Index: " + index + ", Size: " + size);
}else {
MyNode preMyNode = head;
for (int i = 0; i < index; i++) {
preMyNode = preMyNode.next;
}
MyNode nextMyNode = preMyNode.next.next;
preMyNode.next = nextMyNode;
size--;
return true;
}
}
@Override
public Object get(int index) {
if (index < 0 || index >= size) {
throw new IndexOutOfBoundsException("IndexOutOfBounds!!!! Index: "+index+", Size: "+size);
}else {
MyNode preMyNode = head.next;
for (int i = 0; i < index; i++) {
preMyNode = preMyNode.next;
}
return preMyNode.item;
}
}
@Override
public boolean set(int index, Object element) {
if (index < 0 || index >= size) {
throw new IndexOutOfBoundsException("IndexOutOfBounds!!!! Index: "+index+", Size: "+size);
}else {
MyNode preMyNode = head.next;
for (int i = 0; i < index; i++) {
preMyNode = preMyNode.next;
}
preMyNode.item = (E) element;
return true;
}
}
@Override
public int indexOf(Object o) {
MyNode preMyNode = head.next;
for (int i = 0; i < size; i++) {
if (preMyNode.item.equals(o)) {
return i;
}
preMyNode = preMyNode.next;
}
return -1;
}
@Override
public String toString() {
StringBuilder sb = new StringBuilder();
sb.append("[");
MyNode preMyNode = head.next;
for (int i = 0; i < size; i++) {
if (i == size - 1) {
sb.append(preMyNode.item);
} else {
sb.append(preMyNode.item + ",");
}
preMyNode = preMyNode.next;
}
sb.append("]");
return sb.toString();
}
package mylinkedlist;
public class MySingleLinkedTest {
public static void main(String[] args) {
MySingleLinkedList mySingleLinkedList = new MySingleLinkedList<>();
mySingleLinkedList.add(1);
mySingleLinkedList.add(2);
mySingleLinkedList.add(3);
mySingleLinkedList.add(4);
mySingleLinkedList.add(5);
mySingleLinkedList.add(6);
System.out.println("=======Test add(E e)=======");
System.out.println(mySingleLinkedList.toString());
System.out.println("=======Test size()=======");
System.out.println("size="+mySingleLinkedList.size());
System.out.println("=======Test remove(E o) index= 2 =======");
mySingleLinkedList.remove(2);
System.out.println(mySingleLinkedList.toString());
System.out.println("=======Test add(int index, E element) index= 3 value = 66=======");
mySingleLinkedList.add(3,66);
System.out.println(mySingleLinkedList.toString());
System.out.println("=======Test remove(int index) index= 3=======");
mySingleLinkedList.remove(3);
System.out.println(mySingleLinkedList.toString());
System.out.println("=======Test get(int index) index= 3=======");
System.out.println(mySingleLinkedList.get(3));
System.out.println("=======Test set(int index, E element)index= 3 value = 88=======");
mySingleLinkedList.set(3,88);
System.out.println(mySingleLinkedList.toString());
System.out.println("=======Test indexOf(Object o)index= 3 value = 88=======");
System.out.println(mySingleLinkedList.indexOf(88));
System.out.println("=======Test clear()=======");
mySingleLinkedList.clear();
System.out.println(mySingleLinkedList.toString());
}
}
实现MyLink
public class MyLinkedList implements MyLink{
//头节点和为节点不计入链表的长度,也不计入下标!!!!
private int size = 0;
private MyNode first;
private MyNode last;
public MyLinkedList() {
first = new MyNode<>(null,null,null);
last = new MyNode<>(first,null,null);
first.next = last;
}
private class MyNode{
E item;
MyNode next;
MyNode prev;
public MyNode(MyNode prev, E element, MyNode next) {
this.item = element;
this.next = next;
this.prev = prev;
}
}
}
@Override
public int size() {
return size;
}
@Override
public boolean isEmpty() {
return first.next == last ;
}
@Override
public boolean addFirst(E e) {
MyNode nextMyNode = first.next;
MyNode newNode = new MyNode(first,e,nextMyNode);
first.next = newNode;
nextMyNode.prev = newNode;
size++;
return true;
}
//添加到链表尾部
@Override
public boolean add(Object e) {
MyNode preMyNode = last.prev;
MyNode newNode = new MyNode(preMyNode,e,last);
last.prev = newNode;
preMyNode.next = newNode;
size++;
return true;
}
@Override
public boolean remove(E o) {
MyNode n = first;
if(indexOf(o) == -1){
return false;
}else{
for(int i = 0;i= size) {
throw new IndexOutOfBoundsException("IndexOutOfBounds!!!! Index: " + index + ", Size: " + size);
} else if (index == 0) {
addFirst(element);
} else if (index == size - 1) {
add(element);
} else if (index <= size / 2) {
MyNode n = first;
for (int i = 0; i <= index; i++) {
n = n.next;
}
MyNode preMyNode = n.prev;
MyNode newNode = new MyNode(preMyNode, element, n);
preMyNode.next = newNode;
n.prev = newNode;
size++;
} else if (index > size / 2) {
MyNode n = last;
for (int i = size; i > index; i--) {
n = n.prev;
}
MyNode preMyNode = n.prev;
MyNode newNode = new MyNode(preMyNode, element, n);
preMyNode.next = newNode;
n.prev = newNode;
size++;
}
}
@Override
public boolean remove(int index) {
if (index < 0 || index >= size) {
throw new IndexOutOfBoundsException("IndexOutOfBounds!!!! Index: " + index + ", Size: " + size);
}else {
MyNode n = first;
for(int i = 0;i<=index;i++){
n = n.next;
}
MyNode preMyNode = n.prev;
MyNode nextMyNode = n.next;
preMyNode.next = nextMyNode;
nextMyNode.prev = preMyNode;
size--;
return true;
}
}
@Override
public E get(int index) {
if (index < 0 || index >= size) {
throw new IndexOutOfBoundsException("IndexOutOfBounds!!!! Index: " + index + ", Size: " + size);
}else if(index <= size/2){
MyNode n = first;
for(int i = 0;i<=index;i++){
n = n.next;
}
return (E) n.item;
} else if (index > size/2){
MyNode n = last;
for(int i = size;i>index;i--){
n = n.prev;
}
return (E) n.item;
}
return null;
}
@Override
public boolean set(int index, E element) {
if (index < 0 || index >= size) {
throw new IndexOutOfBoundsException("IndexOutOfBounds!!!! Index: " + index + ", Size: " + size);
}else if(index <= size/2){
MyNode n = first;
for(int i = 0;i<=index;i++){
n = n.next;
}
n.item = element;
return true;
} else if (index > size/2){
MyNode n = last;
for(int i = size;i>index;i--){
n = n.prev;
}
n.item = element;
return true;
}
return false;
}
@Override
public int indexOf(Object o) {
MyNode n = first.next;
int index = 0;
while(n.next != null){
if(n.item.equals(o)){
return index;
}
n = n.next;
index++;
}
return -1;
}
@Override
public String toString() {
MyNode n = first.next;
String str = "[";
if(first.next == last){
return "[]";
}
for (int i = 1;i
package mylinkedlist;
import org.junit.jupiter.api.Test;
public class MyLinnkedListTest {
public static void main(String[] args) {
MyLinkedList myLinnkedListTest = new MyLinkedList<>();
myLinnkedListTest.add(1);
myLinnkedListTest.add(2);
myLinnkedListTest.add(3);
myLinnkedListTest.add(4);
myLinnkedListTest.add(5);
myLinnkedListTest.add(6);
System.out.println("=======Test add(E e)=======");
System.out.println(myLinnkedListTest.toString());
System.out.println("=======Test size()=======");
System.out.println("size="+myLinnkedListTest.size());
System.out.println("=======Test remove(E o) index= 2 =======");
myLinnkedListTest.remove(2);
System.out.println(myLinnkedListTest.toString());
System.out.println("=======Test add(int index, E element) index= 3 value = 66=======");
myLinnkedListTest.add(3,66);
System.out.println(myLinnkedListTest.toString());
System.out.println("=======Test remove(int index) index= 3=======");
myLinnkedListTest.remove(3);
System.out.println(myLinnkedListTest.toString());
System.out.println("=======Test get(int index) index= 3=======");
System.out.println(myLinnkedListTest.get(3));
System.out.println("=======Test set(int index, E element)index= 3 value = 88=======");
myLinnkedListTest.set(3,88);
System.out.println(myLinnkedListTest.toString());
System.out.println("=======Test indexOf(Object o)index= 3 value = 88=======");
System.out.println(myLinnkedListTest.indexOf(88));
System.out.println("=======Test clear()=======");
myLinnkedListTest.clear();
System.out.println(myLinnkedListTest.toString());
}
}
有一个整数顺序表L。设计一个尽可能高效的算法删除其中所有值为负整数的元素(假设L中值为负整数的元素可能有多个),删除后元素的相对次序不改变。并给出算法的时间和空间复杂度。例如,L=(1,2,-1,-2,3,-3),删除后L=(1,2,3)。
@Test
public void workOne (){
MyLinkedList integerMyLinkedList = new MyLinkedList<>();
integerMyLinkedList.add(1);
integerMyLinkedList.add(2);
integerMyLinkedList.add(-1);
integerMyLinkedList.add(-2);
integerMyLinkedList.add(3);
integerMyLinkedList.add(-3);
System.out.println("=======before=======");
System.out.println(integerMyLinkedList);
System.out.println("=======after=======");
System.out.println(deleteNegative(integerMyLinkedList));
}
public MyLinkedList deleteNegative(MyLinkedList integerMyLinkedList){
MyLinkedList integerMyLinkedList1 = new MyLinkedList<>();
for (int i = 0; i < integerMyLinkedList.size(); i++) {
if (integerMyLinkedList.get(i) >= 0) {
integerMyLinkedList1.add(integerMyLinkedList.get(i));
}
}
return integerMyLinkedList1;
}
时间复杂度:add方法为O(1),get方法为O(n),所以整体为O(n^n)
空间复杂度O(n)
有一个整数顺序表L。设计一个尽可能高效的算法删除表中值大于等于x且小于等于y的所有元素(x≤y),删除后元素的相对次序不改变。并给出算法的时间和空间复杂度。例如,L=(4,2,1,5,3,6,4),x=2,y=4,删除后L=(1,5,6)。
@Test
public void workTwo (){
MyLinkedList integerMyLinkedList = new MyLinkedList<>();
integerMyLinkedList.add(4);
integerMyLinkedList.add(2);
integerMyLinkedList.add(1);
integerMyLinkedList.add(5);
integerMyLinkedList.add(3);
integerMyLinkedList.add(6);
integerMyLinkedList.add(4);
System.out.println("=======before=======");
System.out.println(integerMyLinkedList);
System.out.println("=======after=======");
System.out.println(deleteOnCondition(integerMyLinkedList,2,4));
}
public MyLinkedList deleteOnCondition(MyLinkedList integerMyLinkedList,int min,int max){
MyLinkedList integerMyLinkedList1 = new MyLinkedList<>();
for (int i = 0; i < integerMyLinkedList.size(); i++) {
if (integerMyLinkedList.get(i) < min || integerMyLinkedList.get(i) > max) {
integerMyLinkedList1.add(integerMyLinkedList.get(i));
}
}
return integerMyLinkedList1;
}
时间复杂度:get方法为O(n),所以整体为O(n^n)
空间复杂度O(n)
有一个整数单链表L,设计一个尽可能高效算法将所有负整数的元素移到其他元素的前面。例如,L=(1,2,-1,-2,3,-3,4),移动后L=(-1,-2,-3,1,2,3,4)。
@Test
public void workOne (){
MySingleLinkedList integerMyLinkedList = new MySingleLinkedList<>();
integerMyLinkedList.add(1);
integerMyLinkedList.add(2);
integerMyLinkedList.add(-1);
integerMyLinkedList.add(-2);
integerMyLinkedList.add(3);
integerMyLinkedList.add(-3);
integerMyLinkedList.add(4);
System.out.println("=======before=======");
System.out.println(integerMyLinkedList);
System.out.println("=======after=======");
System.out.println(moveNegativeFoward(integerMyLinkedList));
}
private MySingleLinkedList moveNegativeFoward(MySingleLinkedList integerMyLinkedList) {
MySingleLinkedList mySingleLinkedList = new MySingleLinkedList();
for (int i = 0; i < integerMyLinkedList.size(); i++) {
if ((int)integerMyLinkedList.get(i) < 0) {
mySingleLinkedList.addFirst(integerMyLinkedList.get(i));
}else {
mySingleLinkedList.add(integerMyLinkedList.get(i));
}
}
return mySingleLinkedList;
}
时间复杂度:addFirst方法为O(1),add方法为O(n),get方法为O(n),所以整体为O(n^n)
空间复杂度O(n)
有两个集合采用整数单链表A、B存储,设计一个算法求两个集合的差集C,C仍然用单链表存储。并给出算法的时间和空间复杂度。例如A=(1,3,2),B=(5,1,4,2),差集C=(3)。
@Test
public void workTwo (){
MySingleLinkedList integerMyLinkedList1 = new MySingleLinkedList<>();
MySingleLinkedList integerMyLinkedList2 = new MySingleLinkedList<>();
integerMyLinkedList1.add(1);
integerMyLinkedList1.add(3);
integerMyLinkedList1.add(2);
integerMyLinkedList2.add(5);
integerMyLinkedList2.add(1);
integerMyLinkedList2.add(4);
integerMyLinkedList2.add(2);
System.out.println("=======before=======");
System.out.println(integerMyLinkedList1);
System.out.println(integerMyLinkedList2);
System.out.println("=======result=======");
System.out.println(deferenceSet(integerMyLinkedList1,integerMyLinkedList2));
}
private MySingleLinkedList deferenceSet(MySingleLinkedList integerMyLinkedList1, MySingleLinkedList integerMyLinkedList2) {
MySingleLinkedList mySingleLinkedList = new MySingleLinkedList();
for (int i = 0;i < integerMyLinkedList1.size;i++){
for (int j = 0;j < integerMyLinkedList2.size;j++) {
if (integerMyLinkedList1.get(i) == integerMyLinkedList2.get(j)) {
break;
} else if (j == integerMyLinkedList2.size - 1) {
mySingleLinkedList.add(integerMyLinkedList1.get(i));
}
}
}
return mySingleLinkedList;
}
时间复杂度:add方法为O(n),get方法为O(n),所以整体为O(n^n^n)
空间复杂度O(n)
https://gitee.com/BenChuat/algorithm-exercise.git