线性表及其逻辑结构
线性表的顺序存储结构----顺序表
顺序表的基本实现JavaScript
class SqList {
constructor() {
this.data = [];
this.length = 0;
this.InitList = function () {
this.length = 0;
};
this.DestroyList = function () {
delete this.data;
this.data = [];
this.length = 0;
};
this.ListEmpty = function () {
return this.length == 0;
};
this.ListLength = function () {
return this.length;
};
this.DisList = function () {
if (this.length == 0)
return;
let str = "";
for (let i = 0; i < this.length; i++) {
str += this.data[i] + " ";
}
console.log(str);
};
this.GeElem = function (i) {
if (i < 0 || i > this.length)
return false;
else
return this.data[i];
};
this.ListAppend = function (e) {
this.data[this.length++] = e;
};
}
}
let l = new SqList();
l.InitList();
l.ListAppend("abc");
l.ListAppend("000");
l.DisList();
let o = new Object();
console.log(l.GeElem(-1));
例题1:以第一个元素为分界线,小于它的放前面,大于它的放后面
void move1(SqList *&L)
{
int i = 1, j = L->length - 1
ElemType firstNum = L->data[0]
ElemType temp
while (i < j)
{
while (i < j && L->data[j] > firstNum)
j--
while (i < j && L->data[i] <= firstNum)
i++
if (i < j)
{
temp = L->data[i]
L->data[i] = L->data[j]
L->data[j] = temp
}
}
temp = L->data[0]
L->data[0] = L->data[i]
L->data[i] = temp
}
void move2(SqList *&L)
{
int firstNum = L->data[0]
int i = 0, j = L->length - 1
while (i < j)
{
while (i < j && L->data[j] > firstNum)
j--
L->data[i] = L->data[j]
i++
while (i < j && L->data[i] <= firstNum)
i++
L->data[j] = L->data[i]
j--
}
L->data[i] = firstNum
}
例题2:删除重复元素 时间复杂度O(n) 空间复杂度O(1)
// 删除重复的元素e 方法一
void DeleteNode1(SqList *&L, ElemType e)
{
int k = 0
for (int i = 0
{
if (L->data[i] != e)
{
L->data[k++] = L->data[i]
}
}
L->length = k
}
// 删除重复元素e 方法二
void DeleteNode2(SqList *&L, ElemType e)
{
int k = 0
for (int i = 0
{
if (L->data[i] != e)
{
L->data[i - k] = L->data[i]
}
else
{
k++
}
}
L->length -= k
}
// 删除重复元素e 方法三
void DeleteNode3(SqList *&L, ElemType e)
{
int i = 0, j = L->length - 1
while (i < j)
{
while (i < j && L->data[i] != e)
i++
while (i < j && L->data[j] == e)
{
j--
L->length--
}
if (i < j)
{
L->data[i] = L->data[j]
j--
L->length--
}
}
}
线性表的链式存储结构----链表
1.单链表
单链表实现JavaScript
//创建一个Node
辅助类,用来生成节点
function Node(value) {
this.value = value
this.next = null
}
//链表类
function LinkedList() {
this.head = null
this.length = 0
//向链表尾部追加元素
this.push = push
//从链表中查找某个元素
this.find = find
//在链表中任意一个元素之后插入一个元素
this.insertAfter = insertAfter
//从链表中查找任意元素节点的前一个节点
this.findPrevious = findPrevious
//从链表中删除值为value的元素
this.remove = remove
//返回当前链表的长度
this.size = size
//查找某个元素在链表中的索引值
this.indexof = indexof
//删除链表中第pos个元素
this.removeAt = removeAt
//获取链表中第一个元素
this.getHead = getHead
//打印当前的链表,供测试用
this.print = print
}
function push(value) {
var node = new Node(value)
if (this.head == null) {
this.head = node
} else {
var current = this.head
while (current.next != null) {
current = current.next
}
current.next = node
}
this.length++
}
function insertAfter(value, item) {
var node = new Node(value)
var current = this.find(item)
if (current == null) {
return console.log('找不到元素')
}
node.next = current.next
current.next = node
length++
}
function remove(value) {
var previous = this.findPrevious(value)
var current = this.find(value)
if (previous == null) {
return console.log('链表中找不到被删除的元素')
}
previous.next = current.next
length--
}
function removeAt(pos) {
if (pos > -1 && pos < length) {
var current = this.head
var index = 0
if (pos === 0) {
this.head = current.next
} else {
while (index < pos) {
var previous = current
current = current.next
index++
}
previous.next = current.next
}
length--
} else {
return null
}
}
function find(value) {
var currentNode = this.head
if (currentNode == null) {
console.log("这是一个空链表!!!")
return null
}
if (currentNode.value === value) {
return currentNode
}
while (currentNode.next) {
currentNode = currentNode.next
if (currentNode.value === value) {
return currentNode
}
}
console.log("没有找到该元素!!!")
return null
}
function findPrevious(value) {
var current = this.head
if (current == null) {
console.log('这是一个空链表')
return null
}
while (current.next) {
current = current.next
if (current.next.value === value) {
return current
}
}
console.log('找不到该元素的前一个元素')
return null
}
function indexof(value) {
var current = this.head
var index = 0
if (current == null) {
return null
} else {
while (current) {
if (current.value === value) {
return index
}
index++
current = current.next
}
}
return -1
}
function size() {
return length
}
function getHead() {
return this.head
}
function print() {
var current = this.head
while (current != null) {
console.log(current.value)
current = current.next
}
}
var list1 = new LinkedList()
console.log(list1)
list1.push(2)
list1.push(4)
list1.push(3)
var list2 = new LinkedList()
list2.push(5)
list2.push(6)
list2.push(4)
例题1:两数相加**
//C++
ListNode *addTwoNumbers(ListNode *l1, ListNode *l2)
{
if (l1->next != NULL && l2->next == NULL)
return l1
if (l1->next == NULL && l2->next != NULL)
return l2
ListNode *l
ListNode *p1 = l1->next, *p2 = l2->next
l = (ListNode *)malloc(sizeof(ListNode))
l->next = NULL
int len1 = ListLength(l1)
int len2 = ListLength(l2)
int len = len1 > len2 ? len1 : len2
int i = 0
bool flag = false
while (i < len)
{
int num1 = (p1 == NULL) ? 0 : p1->val
int num2 = (p2 == NULL) ? 0 : p2->val
int total = num1 + num2
int num = total % 10
int val = num + (flag ? 1 : 0)
InsertFirst(l, val)
flag = total >= 10 ? true : false
i++
p1 = p1->next
p2 = p2->next
}
return l
}
// js
var addTwoNumbers = function (l1, l2) {
let res = new ListNode(null)
let p1 = l1,
p2 = l2,
q = res
let flag = false
while (p1 != null || p2 != null) {
let num1 = (p1 != null) ? p1.val : 0
let num2 = (p2 != null) ? p2.val : 0
let val = (num1 + num2 + (flag ? 1 : 0)) % 10
flag = (num1 + num2 + (flag ? 1 : 0)) >= 10 ? true : false
q.next = new ListNode(val)
q = q.next
if (p1 != null)
p1 = p1.next
if (p2 != null)
p2 = p2.next
}
if (flag)
q.next = new ListNode(1)
return res.next
}
2.双链表
// 头插法
void CreatListF(DLinkList *&L,ELemType a[],int n)
{
DLinkList *s
int i
L = (DLinkList *)malloc(sizeof(DLinkList))
L->prior = L->next = NULL
for(i=0
s = (DLinkList *)malloc(sizeof(DLinkList))
s->data = a[i]
s->next = L->next
if(L->next!=NULL)
L->next->prior = s
L->next = s
s->prior = L
}
}
// 尾插法
void CreatListR(DLinkList *&L,ELemType a[],int n)
{
DLinkList *s,*r
int i
L = (DLinkList *)malloc(sizeof(DLinkList))
r=L
for(i=0
s = (DLinkList *)malloc(sizeof(DLinkList))
s->data = a[i]
r->next=s
r=s
}
r->next=NULL
}
// s插入p之后
s->next = p->next
p->next->prior = s
s->prior = p
p->next = s
// 删除p的后继节点q
p->next = q->next;
p->next->prior = p;
3.循环链表
判断尾节点p的条件是p->next==L
有序表---归并算法
function UnionList(l1, l2) {
let arr = [],
i = 0,
j = 0
let len1 = l1.length,
len2 = l2.length
while (i < len1 && j < len2) {
if (l1[i] < l2[j]) {
arr.push(l1[i])
i++
} else {
arr.push(l2[j])
j++
}
}
while (i < len1) {
arr.push(l1[i])
i++
}
while (j < len2) {
arr.push(l2[j])
j++
}
return arr
}