commit
cc189078e3
95
c-cpp/05_array/array.c
Normal file
95
c-cpp/05_array/array.c
Normal file
@ -0,0 +1,95 @@
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
|
||||
struct array {
|
||||
int size;
|
||||
int used;
|
||||
int *arr;
|
||||
};
|
||||
|
||||
void dump(struct array *array)
|
||||
{
|
||||
int idx;
|
||||
|
||||
for (idx = 0; idx < array->used; idx++)
|
||||
printf("[%02d]: %08d\n", idx, array->arr[idx]);
|
||||
}
|
||||
|
||||
void alloc(struct array *array)
|
||||
{
|
||||
array->arr = (int *)malloc(array->size * sizeof(int));
|
||||
}
|
||||
|
||||
int insert(struct array *array, int elem)
|
||||
{
|
||||
int idx;
|
||||
if (array->used >= array->size)
|
||||
return -1;
|
||||
|
||||
for (idx = 0; idx < array->used; idx++) {
|
||||
if (array->arr[idx] > elem)
|
||||
break;
|
||||
}
|
||||
|
||||
if (idx < array->used)
|
||||
memmove(&array->arr[array->used], &array->arr[idx],
|
||||
(array->used - idx) * sizeof(int));
|
||||
|
||||
array->arr[idx] = elem;
|
||||
array->used++;
|
||||
return idx;
|
||||
}
|
||||
|
||||
int delete(struct array *array, int idx)
|
||||
{
|
||||
if (idx < 0 || idx >= array->used)
|
||||
return -1;
|
||||
|
||||
memmove(&array->arr[idx], &array->arr[idx+1],
|
||||
(array->used - idx) * sizeof(int));
|
||||
array->used--;
|
||||
return 0;
|
||||
}
|
||||
|
||||
int search(struct array *array, int elem)
|
||||
{
|
||||
int idx;
|
||||
|
||||
for (idx = 0; idx < array->used; idx++) {
|
||||
if (array->arr[idx] == elem)
|
||||
return idx;
|
||||
if (array->arr[idx] > elem)
|
||||
return -1;
|
||||
}
|
||||
|
||||
return -1;
|
||||
}
|
||||
|
||||
int main()
|
||||
{
|
||||
int idx;
|
||||
struct array ten_int = {10, 0, NULL};
|
||||
|
||||
alloc(&ten_int);
|
||||
if (!ten_int.arr)
|
||||
return -1;
|
||||
insert(&ten_int, 1);
|
||||
insert(&ten_int, 3);
|
||||
insert(&ten_int, 2);
|
||||
printf("=== insert 1, 3, 2\n");
|
||||
dump(&ten_int);
|
||||
|
||||
idx = search(&ten_int, 2);
|
||||
printf("2 is at position %d\n", idx);
|
||||
idx = search(&ten_int, 9);
|
||||
printf("9 is at position %d\n", idx);
|
||||
|
||||
printf("=== delete [6] element \n");
|
||||
delete(&ten_int, 6);
|
||||
dump(&ten_int);
|
||||
printf("=== delete [0] element \n");
|
||||
delete(&ten_int, 0);
|
||||
dump(&ten_int);
|
||||
return 0;
|
||||
}
|
148
c-cpp/06_linkedlist/list_isPalindrome/LinkList.cpp
Normal file
148
c-cpp/06_linkedlist/list_isPalindrome/LinkList.cpp
Normal file
@ -0,0 +1,148 @@
|
||||
#include "LinkList.h"
|
||||
|
||||
void CreateListHead(LinkList *&L,ElemType a[],int n)
|
||||
{
|
||||
int i;
|
||||
LinkList *s;
|
||||
L = (LinkList *)malloc(sizeof(LinkList));
|
||||
L->next = NULL;
|
||||
for(i = 0;i < n;i++)
|
||||
{
|
||||
s=(LinkList*)malloc(sizeof(LinkList));
|
||||
s->data = a[i];
|
||||
s->next = L->next;
|
||||
L->next = s;
|
||||
}
|
||||
}
|
||||
void CreateListTail(LinkList *&L,ElemType a[],int n)
|
||||
{
|
||||
int i;
|
||||
LinkList * s,* r;
|
||||
L = (LinkList *)malloc(sizeof(LinkList));
|
||||
r = L;
|
||||
for(i = 0;i < n;i++)
|
||||
{
|
||||
s = (LinkList *)malloc(sizeof(LinkList));
|
||||
s->data = a[i];
|
||||
r->next = s;
|
||||
r = s;
|
||||
}
|
||||
r->next = NULL;
|
||||
}
|
||||
void InitList(LinkList *&L)
|
||||
{
|
||||
L=(LinkList *)malloc(sizeof(LinkList));
|
||||
L->next = NULL;
|
||||
}
|
||||
void DestroyList(LinkList *&L)
|
||||
{
|
||||
LinkList * pre = L,*p = L->next;
|
||||
while(p!=NULL)
|
||||
{
|
||||
free(pre);
|
||||
pre = p;
|
||||
p = L->next;
|
||||
}
|
||||
free(pre);
|
||||
}
|
||||
bool ListEmpty(LinkList *L)
|
||||
{
|
||||
return(L->next==NULL);
|
||||
}
|
||||
int ListLength(LinkList *L)
|
||||
{
|
||||
int n = 0;
|
||||
LinkList * p = L;
|
||||
while(p->next!=NULL)
|
||||
{
|
||||
n++;
|
||||
p=p->next;
|
||||
}
|
||||
return(n);
|
||||
}
|
||||
void ShowList(LinkList *L)
|
||||
{
|
||||
LinkList * p = L->next;//Ö¸Ïò¿ªÊ¼½Úµã
|
||||
while(p!=NULL)
|
||||
{
|
||||
printf(" %c ",p->data);
|
||||
p = p->next;
|
||||
}
|
||||
printf("\n");
|
||||
}
|
||||
bool GetListElem(LinkList *L,int i,ElemType &e)
|
||||
{
|
||||
int j = 0;
|
||||
LinkList *p = L;
|
||||
while(j<i&&p!=NULL)
|
||||
{
|
||||
j++;
|
||||
p=p->next;
|
||||
}
|
||||
if(p==NULL)
|
||||
return false;
|
||||
else
|
||||
{
|
||||
e=p->data;
|
||||
return true;
|
||||
}
|
||||
}
|
||||
int LocateElem(LinkList*L,ElemType e)
|
||||
{
|
||||
int i=1;
|
||||
LinkList *p = L->next;
|
||||
while(p!=NULL&&p->data!=e){
|
||||
p=p->next;
|
||||
i++;
|
||||
}
|
||||
if(p==NULL)
|
||||
{
|
||||
return(0);
|
||||
}
|
||||
else
|
||||
return(i);
|
||||
}
|
||||
bool ListInsert(LinkList *&L,int i,ElemType e)
|
||||
{
|
||||
int j=0;
|
||||
LinkList *p =L,*s;
|
||||
while(j<i-1&&p!=NULL)
|
||||
{
|
||||
j++;
|
||||
p=p->next;
|
||||
}
|
||||
if(p==NULL)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
else
|
||||
{
|
||||
s= (LinkList*)malloc(sizeof(LinkList));
|
||||
s->data = e;
|
||||
s->next = p->next;
|
||||
p->next = s;
|
||||
return true;
|
||||
}
|
||||
}
|
||||
bool ListDelete(LinkList *&L,int i,ElemType &e)
|
||||
{
|
||||
int j=0;
|
||||
LinkList * p =L,*q;
|
||||
while(j<i-1&&p!=NULL)
|
||||
{
|
||||
j++;
|
||||
p=p->next;
|
||||
}
|
||||
if(p==NULL)
|
||||
return false;
|
||||
else
|
||||
{
|
||||
q=p->next;
|
||||
if(q==NULL)
|
||||
return false;
|
||||
e=q->data;
|
||||
p->next=q->next;
|
||||
free(q);
|
||||
return true;
|
||||
}
|
||||
}
|
24
c-cpp/06_linkedlist/list_isPalindrome/LinkList.h
Normal file
24
c-cpp/06_linkedlist/list_isPalindrome/LinkList.h
Normal file
@ -0,0 +1,24 @@
|
||||
#ifndef LINKLIST_H
|
||||
#define LINKLIST_H
|
||||
|
||||
#include <stdlib.h>
|
||||
#include <stdio.h>
|
||||
typedef char ElemType;
|
||||
typedef struct LNode
|
||||
{
|
||||
ElemType data;
|
||||
struct LNode*next;
|
||||
}LinkList;
|
||||
|
||||
void CreateListHead(LinkList *&L,ElemType a[],int n);
|
||||
void CreateListTail(LinkList *&L,ElemType a[],int n);
|
||||
void InitList(LinkList *&L);
|
||||
void DestroyList(LinkList *&L);
|
||||
bool ListEmpty(LinkList *L);
|
||||
int ListLength(LinkList *L);
|
||||
void ShowList(LinkList *L);
|
||||
bool GetListElem(LinkList *L,int i,ElemType &e);
|
||||
int LocateElem(LinkList*L,ElemType e);
|
||||
bool ListInsert(LinkList *&L,int i,ElemType e);
|
||||
bool ListDelete(LinkList *&L,int i,ElemType &e);
|
||||
#endif
|
40
c-cpp/06_linkedlist/list_isPalindrome/main.cpp
Normal file
40
c-cpp/06_linkedlist/list_isPalindrome/main.cpp
Normal file
@ -0,0 +1,40 @@
|
||||
#include"LinkList.h"
|
||||
char array1[]= {'a','b','c','b','a'};
|
||||
bool isPalindrome(LinkList * list,int length);
|
||||
int main()
|
||||
{
|
||||
LinkList * list;
|
||||
|
||||
int length = sizeof(array1)/sizeof(array1[0]);
|
||||
InitList(list);
|
||||
CreateListTail(list,array1,length);//用尾插法创建一个单链表
|
||||
if(isPalindrome(list,length))
|
||||
printf("isPalindrome\n");
|
||||
else
|
||||
printf("isNotPalindrome\n");
|
||||
return 0;
|
||||
}
|
||||
bool isPalindrome(LinkList * list,int length)
|
||||
{
|
||||
int i;
|
||||
char buff1[length],buff2[length];
|
||||
ElemType e;
|
||||
for(i=1; i<=length; i++)
|
||||
{
|
||||
GetListElem(list,i,e);//遍历获取链表元素并放入数组中
|
||||
buff1[i-1]=e;//正向数组
|
||||
buff2[length-i]=e;//反向数组
|
||||
}
|
||||
i=0;
|
||||
while(i<=length) {
|
||||
if(buff1[i]==buff2[i])//比较
|
||||
{
|
||||
i++;
|
||||
}
|
||||
else
|
||||
{
|
||||
return false;
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
176
c-cpp/06_linkedlist/single_list.c
Normal file
176
c-cpp/06_linkedlist/single_list.c
Normal file
@ -0,0 +1,176 @@
|
||||
#include <stdio.h>
|
||||
#include <stdbool.h>
|
||||
|
||||
struct single_list {
|
||||
struct single_list *next;
|
||||
int val;
|
||||
};
|
||||
|
||||
struct single_list_head {
|
||||
struct single_list *head;
|
||||
};
|
||||
|
||||
bool is_empty(struct single_list_head *head)
|
||||
{
|
||||
return head->head == NULL;
|
||||
}
|
||||
|
||||
void dump(struct single_list_head *head)
|
||||
{
|
||||
struct single_list *tmp = head->head;
|
||||
int idx = 0;
|
||||
|
||||
while (tmp) {
|
||||
printf("[%02d]: %08d\n", idx++, tmp->val);
|
||||
tmp = tmp->next;
|
||||
}
|
||||
}
|
||||
|
||||
void insert(struct single_list **prev, struct single_list *elem)
|
||||
{
|
||||
if (!prev)
|
||||
return;
|
||||
|
||||
if (*prev)
|
||||
elem->next = *prev;
|
||||
*prev = elem;
|
||||
}
|
||||
|
||||
void insert_head(struct single_list_head *head, struct single_list *elem)
|
||||
{
|
||||
insert(&head->head, elem);
|
||||
}
|
||||
|
||||
struct single_list* delete(struct single_list **prev)
|
||||
{
|
||||
struct single_list *tmp;
|
||||
|
||||
if (!prev)
|
||||
return NULL;
|
||||
|
||||
tmp = *prev;
|
||||
*prev = (*prev)->next;
|
||||
tmp->next = NULL;
|
||||
|
||||
return tmp;
|
||||
}
|
||||
|
||||
struct single_list* delete_head(struct single_list_head* head)
|
||||
{
|
||||
return delete(&head->head);
|
||||
}
|
||||
|
||||
struct single_list** search(struct single_list_head* head, int target)
|
||||
{
|
||||
struct single_list **prev, *tmp;
|
||||
|
||||
for (prev = &head->head, tmp = *prev;
|
||||
tmp && (tmp->val < target);
|
||||
prev = &tmp->next, tmp = *prev)
|
||||
;
|
||||
|
||||
return prev;
|
||||
}
|
||||
|
||||
void reverse(struct single_list_head* head)
|
||||
{
|
||||
struct single_list_head tmp;
|
||||
struct single_list *elem;
|
||||
|
||||
while (!is_empty(head)) {
|
||||
elem = delete_head(head);
|
||||
insert_head(&tmp, elem);
|
||||
}
|
||||
|
||||
head->head = tmp.head;
|
||||
}
|
||||
|
||||
bool is_cyclic(struct single_list_head* head)
|
||||
{
|
||||
struct single_list *s1, *s2;
|
||||
|
||||
s1 = s2 = head->head;
|
||||
|
||||
while(s1 && s2) {
|
||||
s1 = s1->next;
|
||||
s2 = s2->next ? s2->next->next:s2->next;
|
||||
|
||||
if (s1 == s2)
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
struct single_list* middle(struct single_list_head* head)
|
||||
{
|
||||
struct single_list *s1, *s2;
|
||||
struct single_list pseudo_head;
|
||||
|
||||
pseudo_head.next = head->head;
|
||||
s1 = s2 = &pseudo_head;
|
||||
|
||||
while (true) {
|
||||
if (!s2 || !s2->next)
|
||||
return s1;
|
||||
s1 = s1->next;
|
||||
s2 = s2->next->next;
|
||||
}
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
int main()
|
||||
{
|
||||
struct single_list_head head = {NULL};
|
||||
struct single_list lists[10];
|
||||
struct single_list **prev;
|
||||
int idx;
|
||||
|
||||
for (idx = 0; idx < 10; idx++) {
|
||||
lists[idx].val = idx;
|
||||
lists[idx].next = NULL;
|
||||
}
|
||||
|
||||
insert_head(&head, &lists[6]);
|
||||
insert_head(&head, &lists[5]);
|
||||
insert_head(&head, &lists[4]);
|
||||
insert_head(&head, &lists[1]);
|
||||
insert_head(&head, &lists[0]);
|
||||
|
||||
printf("=== insert 0, 1, 4, 5, 6\n");
|
||||
dump(&head);
|
||||
|
||||
prev = search(&head, 2);
|
||||
insert(prev, &lists[2]);
|
||||
printf("=== insert 2\n");
|
||||
dump(&head);
|
||||
|
||||
printf("middle elem is %d\n", middle(&head)->val);
|
||||
|
||||
prev = search(&head, 2);
|
||||
if ((*prev) && ((*prev)->val == 2))
|
||||
printf("The list contains 2\n");
|
||||
else
|
||||
printf("The list not contains 2\n");
|
||||
|
||||
delete(prev);
|
||||
prev = search(&head, 2);
|
||||
printf("After remove 2\n");
|
||||
if ((*prev) && ((*prev)->val == 2))
|
||||
printf("The list contains 2\n");
|
||||
else
|
||||
printf("The list not contains 2\n");
|
||||
dump(&head);
|
||||
|
||||
printf("After reverse \n");
|
||||
reverse(&head);
|
||||
dump(&head);
|
||||
|
||||
printf("middle elem is %d\n", middle(&head)->val);
|
||||
|
||||
lists[0].next = &lists[6];
|
||||
printf("list is%s cyclic\n", is_cyclic(&head)?"":" not");
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
94
javascript/06_linkedlist/SinglyLinkedList.js
Normal file
94
javascript/06_linkedlist/SinglyLinkedList.js
Normal file
@ -0,0 +1,94 @@
|
||||
/**
|
||||
* 1)单链表的插入、删除、查找操作;
|
||||
* 2)链表中存储的是int类型的数据;
|
||||
*/
|
||||
class Node {
|
||||
constructor (element) {
|
||||
this.element = element
|
||||
this.next = null
|
||||
}
|
||||
}
|
||||
|
||||
class LinkedList {
|
||||
constructor () {
|
||||
this.head = new Node('head')
|
||||
}
|
||||
// 根据value查找节点
|
||||
findByValue (item) {
|
||||
let currentNode = this.head
|
||||
while (currentNode !== null && currentNode.element !== item) {
|
||||
currentNode = currentNode.next
|
||||
}
|
||||
console.log(currentNode)
|
||||
return currentNode === null ? -1 : currentNode
|
||||
}
|
||||
|
||||
// 根据index查找节点
|
||||
findByIndex (index) {
|
||||
let currentNode = this.head
|
||||
let pos = 0
|
||||
while (currentNode !== null && pos !== index) {
|
||||
currentNode = currentNode.next
|
||||
pos++
|
||||
}
|
||||
console.log(currentNode)
|
||||
return currentNode === null ? -1 : currentNode
|
||||
}
|
||||
|
||||
// 指定元素向后插入
|
||||
insert (newElement, element) {
|
||||
const currentNode = this.findByValue(element)
|
||||
if (currentNode === -1) {
|
||||
console.log('未找到插入位置')
|
||||
return
|
||||
}
|
||||
const newNode = new Node(newElement)
|
||||
newNode.next = currentNode.next
|
||||
currentNode.next = newNode
|
||||
}
|
||||
|
||||
// 查找前一个
|
||||
findPrev (item) {
|
||||
let currentNode = this.head
|
||||
while (currentNode.next !== null && currentNode.next.element !== item) {
|
||||
currentNode = currentNode.next
|
||||
}
|
||||
if (currentNode.next === null) {
|
||||
return -1
|
||||
}
|
||||
return currentNode
|
||||
}
|
||||
|
||||
// 根据值删除
|
||||
remove (item) {
|
||||
const desNode = this.findByValue(item)
|
||||
if (desNode === -1) {
|
||||
console.log('未找到元素')
|
||||
return
|
||||
}
|
||||
const prevNode = this.findPrev(item)
|
||||
prevNode.next = desNode.next
|
||||
}
|
||||
|
||||
// 遍历显示所有节点
|
||||
display () {
|
||||
let currentNode = this.head
|
||||
while (currentNode !== null) {
|
||||
console.log(currentNode.element)
|
||||
currentNode = currentNode.next
|
||||
}
|
||||
}
|
||||
}
|
||||
// Test
|
||||
const LList = new LinkedList()
|
||||
LList.insert('chen', 'head')
|
||||
LList.insert('curry', 'chen')
|
||||
LList.insert('sang', 'head')
|
||||
LList.insert('zhao', 'head')
|
||||
console.log('-------------remove item------------')
|
||||
LList.remove('curry', 'chen')
|
||||
LList.display()
|
||||
console.log('-------------find by item------------')
|
||||
LList.findByValue('chen')
|
||||
console.log('-------------find by index------------')
|
||||
LList.findByIndex(2)
|
221
javascript/07_linkedlist/LinkedListAlgo.js
Normal file
221
javascript/07_linkedlist/LinkedListAlgo.js
Normal file
@ -0,0 +1,221 @@
|
||||
/**
|
||||
* 1) 单链表反转
|
||||
* 2) 链表中环的检测
|
||||
* 3) 两个有序的链表合并
|
||||
* 4) 删除链表倒数第n个结点
|
||||
* 5) 求链表的中间结点
|
||||
*
|
||||
*/
|
||||
class Node {
|
||||
constructor(element) {
|
||||
this.element = element
|
||||
this.next = null
|
||||
}
|
||||
}
|
||||
|
||||
class LinkedList {
|
||||
constructor() {
|
||||
this.head = new Node('head')
|
||||
}
|
||||
// 根据value查找节点
|
||||
findByValue(item) {
|
||||
let currentNode = this.head
|
||||
while (currentNode !== null && currentNode.element !== item) {
|
||||
currentNode = currentNode.next
|
||||
}
|
||||
return currentNode === null ? -1 : currentNode
|
||||
}
|
||||
// 根据index查找节点
|
||||
findByIndex(index) {
|
||||
let currentNode = this.head
|
||||
let pos = 0
|
||||
while (currentNode !== null && pos !== index) {
|
||||
currentNode = currentNode.next
|
||||
pos++
|
||||
}
|
||||
return currentNode === null ? -1 : pos
|
||||
}
|
||||
// 指定元素向后插入
|
||||
insert(newElement, element) {
|
||||
const currentNode = this.findByValue(element)
|
||||
if (currentNode === -1) {
|
||||
console.log('未找到插入位置')
|
||||
return
|
||||
}
|
||||
const newNode = new Node(newElement)
|
||||
newNode.next = currentNode.next
|
||||
currentNode.next = newNode
|
||||
}
|
||||
// 查找前一个
|
||||
findPrev(item) {
|
||||
let currentNode = this.head
|
||||
while (currentNode.next !== null && currentNode.next.element !== item) {
|
||||
currentNode = currentNode.next
|
||||
}
|
||||
if (currentNode.next === null) {
|
||||
return -1
|
||||
}
|
||||
return currentNode
|
||||
}
|
||||
// 根据值删除
|
||||
remove(item) {
|
||||
const desNode = this.findByValue(item)
|
||||
if (desNode === -1) {
|
||||
console.log('未找到元素')
|
||||
return
|
||||
}
|
||||
const prevNode = this.findPrev(item)
|
||||
prevNode.next = desNode.next
|
||||
}
|
||||
// 遍历显示所有节点
|
||||
display() {
|
||||
let currentNode = this.head
|
||||
while (currentNode !== null) {
|
||||
console.log(currentNode.element)
|
||||
currentNode = currentNode.next
|
||||
}
|
||||
}
|
||||
|
||||
// 尾插法 反转单链表
|
||||
reverseList() {
|
||||
const root = new Node('head')
|
||||
let currentNode = this.head.next
|
||||
while (currentNode !== null) {
|
||||
const next = currentNode.next
|
||||
currentNode.next = root.next
|
||||
root.next = currentNode
|
||||
currentNode = next
|
||||
}
|
||||
this.head = root
|
||||
}
|
||||
|
||||
// 自己一开始瞎想的。差距啊
|
||||
reverseList2() {
|
||||
let currentNode = this.head.next
|
||||
let reverseList = new LinkedList()
|
||||
const tempArr = []
|
||||
if (currentNode === null || currentNode.next === null) {
|
||||
console.log('节点数小于3,不反转')
|
||||
return
|
||||
}
|
||||
while (currentNode !== null) {
|
||||
tempArr.push(currentNode)
|
||||
currentNode = currentNode.next
|
||||
}
|
||||
for (let i = tempArr.length - 1; i >= 0; i--) {
|
||||
const key = i === tempArr.length - 1 ? 'head' : tempArr[i + 1].element
|
||||
reverseList.insert(tempArr[i].element, key)
|
||||
}
|
||||
reverseList.display()
|
||||
return reverseList
|
||||
}
|
||||
// 环验证
|
||||
checkCircle() {
|
||||
let fast = this.head.next
|
||||
let slow = this.head
|
||||
while (fast !== null && fast.next !== null) {
|
||||
fast = fast.next.next
|
||||
slow = slow.next
|
||||
if (slow === fast) return true
|
||||
}
|
||||
return false
|
||||
}
|
||||
// 删除倒数第k个节点
|
||||
removeByIndexFromEnd(index) {
|
||||
let pos = 1
|
||||
this.reverseList()
|
||||
let currentNode = this.head.next
|
||||
while (currentNode !== null && pos < index) {
|
||||
currentNode = currentNode.next
|
||||
pos++
|
||||
}
|
||||
if (currentNode === null) {
|
||||
console.log('无法删除最后一个节点或者该节点不存在')
|
||||
return false
|
||||
}
|
||||
this.remove(currentNode.element)
|
||||
this.reverseList()
|
||||
}
|
||||
// 求中间节点
|
||||
findMiddleNode() {
|
||||
let fast = this.head
|
||||
let slow = this.head
|
||||
while (fast.next !== null && fast.next.next !== null) {
|
||||
fast = fast.next.next
|
||||
slow = slow.next
|
||||
}
|
||||
console.log(slow)
|
||||
return slow
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
const mergeSortedLists = (listA, listB) => {
|
||||
if (!listA) {
|
||||
return listB
|
||||
}
|
||||
if (!listB) {
|
||||
return listA
|
||||
}
|
||||
|
||||
let a = listA
|
||||
let b = listB
|
||||
let resultList = undefined
|
||||
if (a.element < b.element) {
|
||||
resultList = a
|
||||
a = a.next
|
||||
} else {
|
||||
resultList = b
|
||||
b = b.next
|
||||
}
|
||||
let currentNode = resultList
|
||||
while (a !== null && b !== null) {
|
||||
if (a.element < b.element) {
|
||||
currentNode.next = a
|
||||
a = a.next
|
||||
} else {
|
||||
currentNode.next = b
|
||||
b = b.next
|
||||
}
|
||||
currentNode = currentNode.next
|
||||
}
|
||||
|
||||
if (a != null) {
|
||||
currentNode.next = a
|
||||
} else {
|
||||
currentNode.next = b
|
||||
}
|
||||
return resultList
|
||||
}
|
||||
|
||||
// Test
|
||||
const LList = new LinkedList()
|
||||
LList.insert('chen', 'head')
|
||||
LList.insert('curry', 'chen')
|
||||
LList.insert('sang', 'head')
|
||||
LList.insert('zhao', 'head')
|
||||
console.log('-------------start reverse------------')
|
||||
LList.reverseList()
|
||||
LList.display()
|
||||
console.log('-------------check circle------------')
|
||||
console.log(LList.checkCircle())
|
||||
console.log('-------------remove the one before last ------------')
|
||||
LList.removeByIndexFromEnd(2)
|
||||
LList.display()
|
||||
|
||||
const sortedList1 = new LinkedList()
|
||||
sortedList1.insert(9, 'head')
|
||||
sortedList1.insert(8, 'head')
|
||||
sortedList1.insert(7, 'head')
|
||||
sortedList1.insert(6, 'head')
|
||||
const sortedList2 = new LinkedList()
|
||||
sortedList2.insert(21, 'head')
|
||||
sortedList2.insert(20, 'head')
|
||||
sortedList2.insert(19, 'head')
|
||||
sortedList2.insert(18, 'head')
|
||||
console.log('-------------sort two list ------------')
|
||||
let sortedList = mergeSortedLists(sortedList1.head.next, sortedList2.head.next)
|
||||
while (sortedList !== null) {
|
||||
console.log(sortedList.element)
|
||||
sortedList = sortedList.next
|
||||
}
|
139
python/06_linkedlist/singly_linked_list.py
Normal file
139
python/06_linkedlist/singly_linked_list.py
Normal file
@ -0,0 +1,139 @@
|
||||
"""
|
||||
1) Insertion, deletion and search of singly-linked list;
|
||||
2) Assumes int type for data in list nodes.
|
||||
|
||||
Author: Wenru
|
||||
"""
|
||||
from typing import Optional
|
||||
|
||||
class Node:
|
||||
|
||||
def __init__(self, data: int, next=None):
|
||||
self.data = data
|
||||
self._next = next
|
||||
|
||||
|
||||
class SinglyLinkedList:
|
||||
|
||||
def __init__(self):
|
||||
self._head = None
|
||||
|
||||
def find_by_value(self, value: int) -> Optional[Node]:
|
||||
p = self._head
|
||||
while p and p.data != value:
|
||||
p = p._next
|
||||
|
||||
return p
|
||||
|
||||
def find_by_index(self, index: int) -> Optional[Node]:
|
||||
p = self._head
|
||||
position = 0
|
||||
while p and position != index:
|
||||
p = p._next
|
||||
position += 1
|
||||
|
||||
return p
|
||||
|
||||
def insert_value_to_head(self, value: int):
|
||||
new_node = Node(value)
|
||||
self.insert_node_to_head(new_node)
|
||||
|
||||
def insert_node_to_head(self, new_node: Node):
|
||||
if new_node:
|
||||
new_node._next = self._head
|
||||
self._head = new_node
|
||||
|
||||
def insert_value_after(self, node: Node, value: int):
|
||||
new_node = Node(value)
|
||||
self.insert_node_after(node, new_node)
|
||||
|
||||
def insert_node_after(self, node: Node, new_node: Node):
|
||||
if not node or not new_node:
|
||||
return
|
||||
new_node._next = node._next
|
||||
node._next = new_node
|
||||
|
||||
def insert_value_before(self, node: Node, value: int):
|
||||
new_node = Node(value)
|
||||
self.insert_node_before(node, new_node)
|
||||
|
||||
def insert_node_before(self, node: Node, new_node: Node):
|
||||
if not self._head or not node or not new_node:
|
||||
return
|
||||
if self._head == node:
|
||||
self.insert_node_to_head(new_node)
|
||||
return
|
||||
current = self._head
|
||||
while current._next and current._next != node:
|
||||
current = current._next
|
||||
if not current._next: # node is not even in the list
|
||||
return
|
||||
new_node._next = node
|
||||
current._next = new_node
|
||||
|
||||
def delete_by_node(self, node: Node):
|
||||
if not self._head or not node:
|
||||
return
|
||||
if node._next:
|
||||
node.data = node._next.data
|
||||
node._next = node._next._next
|
||||
return
|
||||
# node is the last one or not in the list
|
||||
current = self._head
|
||||
while current and current._next != node:
|
||||
current = current._next
|
||||
if not current: # node not in the list
|
||||
return
|
||||
current._next = None
|
||||
|
||||
def delete_by_value(self, value: int):
|
||||
if not self._head or not value:
|
||||
return
|
||||
fake_head = Node(value+1)
|
||||
fake_head._next = self._head
|
||||
prev, current = fake_head, self._head
|
||||
while current:
|
||||
if current.data != value:
|
||||
prev._next = current
|
||||
prev = prev._next
|
||||
current = current._next
|
||||
if prev._next:
|
||||
prev._next = None
|
||||
self._head = fake_head._next # in case head.data == value
|
||||
|
||||
def __repr__(self) -> str:
|
||||
nums = []
|
||||
current = self._head
|
||||
while current:
|
||||
nums.append(current.data)
|
||||
current = current._next
|
||||
if len(nums) > 0:
|
||||
return "->".join(str(num) for num in nums)
|
||||
else:
|
||||
return ""
|
||||
|
||||
def print_all(self):
|
||||
current = self._head
|
||||
if current:
|
||||
print(f"{current.data}", end="")
|
||||
current = current._next
|
||||
while current:
|
||||
print(f"->{current.data}", end="")
|
||||
current = current._next
|
||||
print("\n", flush=True)
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
l = SinglyLinkedList()
|
||||
for i in range(15):
|
||||
l.insert_value_to_head(i)
|
||||
node9 = l.find_by_value(9)
|
||||
l.insert_value_before(node9, 20)
|
||||
l.insert_value_before(node9, 16)
|
||||
l.insert_value_before(node9, 16)
|
||||
l.delete_by_value(16)
|
||||
node11 = l.find_by_index(3)
|
||||
l.delete_by_node(node11)
|
||||
l.delete_by_node(l._head)
|
||||
l.delete_by_value(13)
|
||||
print(l)
|
92
python/07_linkedlist/linked_list_algo.py
Normal file
92
python/07_linkedlist/linked_list_algo.py
Normal file
@ -0,0 +1,92 @@
|
||||
"""
|
||||
1) Reverse singly-linked list
|
||||
2) Detect cycle in a list
|
||||
3) Merge two sorted lists
|
||||
4) Remove nth node from the end
|
||||
5) Find middle node
|
||||
|
||||
Author: Wenru
|
||||
"""
|
||||
|
||||
from typing import Optional
|
||||
|
||||
|
||||
class Node:
|
||||
|
||||
def __init__(self, data: int, next=None):
|
||||
self.data = data
|
||||
self._next = next
|
||||
|
||||
# Reverse singly-linked list
|
||||
# 单链表反转
|
||||
# Note that the input is assumed to be a Node, not a linked list.
|
||||
def reverse(head: Node) -> Optional[Node]:
|
||||
reversed_head = None
|
||||
current = head
|
||||
while current:
|
||||
reversed_head, reversed_head._next, current = current, reversed_head, current._next
|
||||
return reversed_head
|
||||
|
||||
# Detect cycle in a list
|
||||
# 检测环
|
||||
def has_cycle(head: Node) -> bool:
|
||||
slow, fast = head, head
|
||||
while fast and fast._next:
|
||||
slow = slow._next
|
||||
fast = fast._next._next
|
||||
if slow == fast:
|
||||
return True
|
||||
return False
|
||||
|
||||
# Merge two sorted linked list
|
||||
# 有序链表合并
|
||||
def merge_sorted_list(l1: Node, l2: Node) -> Optional[Node]:
|
||||
if l1 and l2:
|
||||
p1, p2 = l1, l2
|
||||
fake_head = Node(None)
|
||||
current = fake_head
|
||||
while p1 and p2:
|
||||
if p1.data <= p2.data:
|
||||
current._next = p1
|
||||
p1 = p1._next
|
||||
else:
|
||||
current._next = p2
|
||||
p2 = p2._next
|
||||
current = current._next
|
||||
current._next = p1 if p1 else p2
|
||||
return fake_head._next
|
||||
return p1 or p2
|
||||
|
||||
# Remove nth node from the end
|
||||
# 删除倒数第n个节点。假设n大于0
|
||||
def remove_nth_from_end(head: Node, n: int) -> Optional[Node]:
|
||||
fast = head
|
||||
count = 0
|
||||
while fast and count < n:
|
||||
fast = fast._next
|
||||
count += 1
|
||||
if not fast and count < n: # not that many nodes
|
||||
return head
|
||||
if not fast and count == n:
|
||||
return head._next
|
||||
|
||||
slow = head
|
||||
while fast._next:
|
||||
fast, slow = fast._next, slow._next
|
||||
slow._next = slow._next._next
|
||||
return head
|
||||
|
||||
def find_middle_node(head: Node) -> Optional[Node]:
|
||||
slow, fast = head, head
|
||||
fast = fast._next if fast else None
|
||||
while fast and fast._next:
|
||||
slow, fast = slow._next, fast._next._next
|
||||
return slow
|
||||
|
||||
def print_all(head: Node):
|
||||
nums = []
|
||||
current = head
|
||||
while current:
|
||||
nums.append(current.data)
|
||||
current = current._next
|
||||
print("->".join(str(num) for num in nums))
|
Loading…
Reference in New Issue
Block a user