Related
Is there any way to store the value of the pointer inside a self-referential structure and then use it to modify the pointer instead of the structure it points to?
I'm trying to perform bst deletion using the following code:
struct node *temp = start;
struct node *parent = start;
int isRight = 0, flag = 0;
while(temp != NULL)
{
if(temp->data == key)
{
if(isRight == 1)
parent = parent->rlink;
else
parent = parent->llink;
if(temp->rlink != NULL)
{
if(temp->llink != NULL)
{
replace(temp->llink, temp->rlink);
}
parent = temp->rlink;
}
else if(temp->llink != NULL)
{
parent = temp->llink;
}
else
{
parent = NULL;
}
flag = 1;
break;
}
else if(temp->data < key)
{
parent = temp;
isRight = 1;
temp = temp->rlink;
}
else
{
parent = temp;
isRight = 0;
temp = temp->llink;
}
}
where:
void replace(struct node *temp, struct node *root)
{
while(root->llink != NULL)
{
root = root->llink;
}
root->llink = temp;
}
The problem is that parent = parent->llink/rlink just makes it so that the pointer parent points to the node that is in the parent->llink part of the node.
Is there any way to rewrite this code so that I can make the parent refer to the memory location inside the node parent which stores the link to the next node instead of the node itself?
I can rewrite this code to assign values directly to parent->llink/rlink by checking isRight for each case, but the code looks too clunky.
(This is not the actual way to perform bst deletion, but I'm trying to solve this on a whim.)
I am trying to solve a problem which is: Find all ancestors of a particular node in a binary tree.
Input: root, targetNode
Output: An array/list containing the ancestors
Suppose, we have the above binary tree as an example. We want to find the ancestors of the node 4. The output should be [3, 5, 2, 4]. If the node is 8, the output is [3, 1, 8]
To solve this, I have written a function which implements DFS.
var ancestor = function(root, target) {
var isFound = false;
const dfs = (node, curr) => {
if (node === null) {
return curr;
}
if (node.val === target.val) {
curr.push(node.val);
isFound = true;
return curr;
}
curr.push(node.val);
const left = dfs(node.left, curr);
if (!isFound) {
const right = dfs(node.right, curr);
curr.pop();
return right;
} else {
curr.pop();
return left;
}
}
console.log(dfs(root, []));
};
But it is not returning the correct ouput. For example, if the targetNode is 7, the output is [3], if the targetNode is 8, the output is also [3]. If I remove the line curr.pop() the output is also invalid. for targetNode 7 it is [3 , 5, 6, 2, 7]. I think I found the issue where I am making mistake. While backtracking, I am doing something wrong with the remove of the node that was pushed in the curr array. If I pass a string instead of the array, it prints the output correctly.
var ancestor = function(root, target) {
var isFound = false;
const dfs = (node, curr) => {
if (node === null) {
return curr;
}
if (node.val === target.val) {
curr += node.val;
isFound = true;
return curr;
}
const left = dfs(node.left, curr + node.val + '->);
if (!isFound) {
const right = dfs(node.right, curr + node.val + '->);
return right;
} else {
return left;
}
}
console.log(dfs(root, ''));
The above code with string instead of array prints the output correctly, If I pass targetNode 7, output is 3->5->2->7
My question is, how to properly unchoose/backtrack here? Or is there anything else that I am doing incorrectly? Thanks in advance.
recursion in its natural setting
Recursion is a functional heritage and so using it with functional style yields the best results. This means avoiding imperative things such as mutations like push and cur += node.val, variable reassignments like isFound = true, and other side effects. We can write ancestor as a simple generator-based function that prepends each node to the output of recursive sub-problem -
const empty =
Symbol("tree.empty")
function node(val, left = empty, right = empty) {
return { val, left, right }
}
function* ancestor(t, q) {
if (t == empty) return
if (t.val == q) yield [t.val]
for (const l of ancestor(t.left, q)) yield [t.val, ...l]
for (const r of ancestor(t.right, q)) yield [t.val, ...r]
}
const mytree =
node(3, node(5, node(6), node(2, node(7), node(4))), node(1, node(0), node(8)))
for (const path of ancestor(mytree, 7))
console.log(path.join("->"))
3->5->2->7
use modules
To finish, I would recommend a module-based approach for this code -
// tree.js
const empty =
Symbol("tree.empty")
function node(val, left = empty, right = empty) {
return { val, left, right }
}
function* ancestor(t, q) {
if (t == empty) return
if (t.val == q) yield [t.val]
for (const l of ancestor(t.left, q)) yield [t.val, ...l]
for (const r of ancestor(t.right, q)) yield [t.val, ...r]
}
function insert(t, val) {
// ...
}
function remove(t, val) {
// ...
}
function fromArray(a) {
// ...
}
// other tree functions...
export { empty, node, ancestor, insert, remove, fromArray }
// main.js
import { node, ancestor } from "./tree.js"
const mytree =
node(3, node(5, node(6), node(2, node(7), node(4))), node(1, node(0), node(8)))
for (const path of ancestor(mytree, 7))
console.log(path.join("->"))
3->5->2->7
private generator
In the previous implementation, our module exposes a generator for ancestor's public interface. Another option is to return undefined when a node cannot be found and has no ancestry. Consider this alternate implementation which hides the generator and requires the caller to null-check the result instead -
const empty =
Symbol("tree.empty")
function node(val, left = empty, right = empty) {
return { val, left, right }
}
function ancestor(t, q) {
function* dfs(t) {
if (t == empty) return
if (t.val == q) yield [t.val]
for (const l of dfs(t.left)) yield [t.val, ...l]
for (const r of dfs(t.right)) yield [t.val, ...r]
}
return Array.from(dfs(t))[0]
}
const mytree =
node(3, node(5, node(6), node(2, node(7), node(4))), node(1, node(0), node(8)))
const result =
ancestor(mytree, 7)
if (result)
console.log(result.join("->"))
else
console.log("no result")
3->5->2->7
You need to check whether the DFS of the right child has found the node.
fix:
const left = dfs(node.left, curr);
if (!isFound) {
const right = dfs(node.right, curr);
if(isFound) {
return right;
}
curr.pop();
return; // return nothing, backtracking
}
return left;
In the array example, your loop iterates through the nodes in a DFS manner, so each of those nodes are connected in that manner. If we count the tree nodes in DFS algorithm, [3 , 5, 6, 2, 7] are actually in order 1, 2, 3, 4 and 5. In this manner, your whole tree in an array should be looking like this; [3 , 5, 6, 2, 7, 4, 1, 0, 8].
So when you find the target value, you pop from the current node and trace it all back up to the head node in DFS algorithm.
I'd either suggest finding a way to get around that, or you could save each of these node's parents. Meaning you could use tuples instead of int arrays (if that's acceptable). An index could look like this = (node value, parent value)
[(3,NULL),(5,3),(6,5),(2,5)...]
And then traceback accordingly...
I would like to be able to find keys in a Rust BTreeSet that are strictly lower and greater than a specified key.
For example, given the set { "1", "3" }, and the search key is "2" then the answer should be ("1", "3"). In the cases either where either lower or greater value does not exist None should be returned.
I can achieve the result that I am looking for by calling the range() method on the BTreeSet twice.
Is there is a way to do this using a single search, like there is in C++? C++'s std::set has a bi-directional iterator:
// $CXX -std=c++17 less-than.c++ -o less-than && ./less-than
#include <cassert>
#include <optional>
#include <set>
#include <string>
#include <iostream>
using std::optional;
using std::pair;
using std::set;
using std::string;
pair<optional<string>, optional<string>> bounding_box(
const set<string>& space,
const string& point)
{
if (space.empty()) { return {}; }
optional<string> gt_bound;
optional<string> lt_bound;
const auto ge_bound_it = space.lower_bound(point);
if (ge_bound_it != space.end()) {
if (*ge_bound_it == point) {
// lower_bound returned an equal point, use the next one
// if it exists
const auto gt_bound_it = std::next(ge_bound_it, 1);
if (gt_bound_it != space.end()) {
gt_bound = *gt_bound_it;
}
} else {
gt_bound = *ge_bound_it;
}
}
if (ge_bound_it != space.begin()) {
lt_bound = *std::next(ge_bound_it, -1);
}
return {lt_bound, gt_bound};
}
int main() {
{
const auto box = bounding_box({"1", "3"}, "2");
assert(box.first);
assert(*box.first == "1");
assert(box.second);
assert(*box.second == "3");
}
{
const auto box = bounding_box({"1", "3"}, "4");
assert(box.first);
assert(*box.first == "3");
assert(!box.second);
}
{
const auto box = bounding_box({"1", "3"}, "0");
assert(!box.first);
assert(box.second);
assert(*box.second == "1");
}
{
const auto box = bounding_box({"3", "3"}, "3");
assert(!box.first);
assert(!box.second);
}
{
const auto box = bounding_box({"3", "4"}, "3");
assert(!box.first);
assert(box.second);
assert(*box.second == "4");
}
{
const auto box = bounding_box({}, "3");
assert(!box.first);
assert(!box.second);
}
}
The search method is a bit of a hot spot and I wonder if there is an idiomatic way to do this in Rust.
No, there is no way to do this in a single search; you need to call range twice.
There have been discussions about enhancing BTreeMap / BTreeSet to have a "cursor" API. Recently, a pull request was opened to do so, but it was closed because it was deemed that there should be more discussion about how such an API should look and work.
Perhaps you will be the one to spearhead the discussion about such an API?
See also:
How to get the lower bound and upper bound of an element in Rust BTreeSet?
There is not a cursor API in Rust, as said in Shepmaster's answer. You can sometimes simulate it when your iterator implements DoubleEndedIterator with next() and next_back().
However, if I understand well what you are trying to do, you do not need this stuff because a set is ordered. You can write your code by going through each pair and stop when the second item is greater than your "point":
use std::collections::BTreeSet;
fn find_bounds<'a>(set: &'a BTreeSet<&str>, point: &str) -> (Option<&'a str>, Option<&'a str>) {
let mut it = set.iter();
let mut lower = match it.next() {
None => return (None, None),
Some(s) if *s > point => return (None, Some(s)),
Some(s) => s,
};
while let Some(upper) = it.next() {
if *upper > point {
return (Some(lower), Some(*upper));
}
lower = upper;
}
(Some(lower), None)
}
#[test]
fn tests() {
let mut s = BTreeSet::new();
s.insert("a");
s.insert("c");
s.insert("t");
s.insert("g");
assert_eq!(find_bounds(&s, "f"), (Some("c"), Some("g")));
assert_eq!(find_bounds(&s, "z"), (Some("t"), None));
assert_eq!(find_bounds(&s, " "), (None, Some("a")));
}
The code is not well written, but it works.
Here is what I've done so far:
struct rep_list {
struct node *head;
struct node *tail;
}
typedef rep_list *list;
int length(const list lst) {
if (lst->head == NULL) {
return 0;
}
else {
lst->head = lst->head->next;
return 1 + length(lst);
}
}
This works, but the head of the list the function accepts as a parameter gets changed. I don't know how to fix that.
I'm not allowed to change the function definition so it should always accept a list variable.
Any ideas?
EDIT: I tried to do what Tyler S suggested in the comments but I encountered another problem. If I create a node* variable at the beginning, it should point to lst->head. But then every recursive call to the function changes the value back to lst->head and I cannot move forward.
You don't need a local node: just don't change the list head. Instead, pass the next pointer as the recursion head.
int length(const list lst) {
if (lst->head == NULL) {
return 0;
}
else {
return 1 + length(lst->head-next);
}
}
I see. Okay; this gets a bit clunky because of the chosen representation. You need a temporary variable to contain the remaining list. This iscludes changing the head.
int length(const list lst) {
if (lst->head == NULL) {
return 0;
}
else {
new_lst = new(list)
new_lst->head = lst->head->next;
var result = 1 + length(new_lst);
free(new_lst)
return result
}
}
At each recursion step, you create a new list object, point it to the 2nd element of the current list, and continue. Does this do the job for you?
Although this solution is clunky and I hate it, its the only way I can see to accomplish what you're asking without modifying the method signature. We create a temporary node * as member data of the class and modify it when we start.
struct rep_list {
struct node *head;
struct node *tail;
}
node *temp = NULL;
bool didSetHead = false;
typedef rep_list *list;
int length(const list lst) {
if ((didSetHead) && (lst->head != temp)) {
temp = lst->head;
didSetHead = false;
}
if (temp == NULL) {
didSetHead = true;
return 0;
}
else {
temp = temp->next;
return 1 + length(temp);
}
}
Please note, I haven't tested this code and you may have to play with a bit, but the idea will work.
I'm wondering if I can somehow use an x, y pair as the key to my dictionary
let activeSquares = Dictionary <(x: Int, y: Int), SKShapeNode>()
But I get the error:
Cannot convert the expression's type '<<error type>>' to type '$T1'
and the error:
Type '(x: Int, y: Int)?' does not conform to protocol 'Hashable'
So.. how can we make it conform?
The definition for Dictionary is struct Dictionary<KeyType : Hashable, ValueType> : ..., i.e. the type of the key must conform to the protocol Hashable. But the language guide tells us that protocols can be adopted by classes, structs and enums, i.e. not by tuples. Therefore, tuples cannot be used as Dictionary keys.
A workaround would be defining a hashable struct type containing two Ints (or whatever you want to put in your tuple).
As mentioned in the answer above, it is not possible. But you can wrap tuple into generic structure with Hashable protocol as a workaround:
struct Two<T:Hashable,U:Hashable> : Hashable {
let values : (T, U)
var hashValue : Int {
get {
let (a,b) = values
return a.hashValue &* 31 &+ b.hashValue
}
}
}
// comparison function for conforming to Equatable protocol
func ==<T:Hashable,U:Hashable>(lhs: Two<T,U>, rhs: Two<T,U>) -> Bool {
return lhs.values == rhs.values
}
// usage:
let pair = Two(values:("C","D"))
var pairMap = Dictionary<Two<String,String>,String>()
pairMap[pair] = "A"
Unfortunately, as of Swift 4.2 the standard library still doesn't provide conditional conformance to Hashable for tuples and this is not considered valid code by the compiler:
extension (T1, T2): Hashable where T1: Hashable, T2: Hashable {
// potential generic `Hashable` implementation here..
}
In addition, structs, classes and enums having tuples as their fields won't get Hashable automatically synthesized.
While other answers suggested using arrays instead of tuples, this would cause inefficiencies. A tuple is a very simple structure that can be easily optimized due to the fact that the number and types of elements is known at compile-time. An Array instance almost always preallocates more contiguous memory to accommodate for potential elements to be added. Besides, using Array type forces you to either make item types the same or to use type erasure. That is, if you don't care about inefficiency (Int, Int) could be stored in [Int], but (String, Int) would need something like [Any].
The workaround that I found relies on the fact that Hashable does synthesize automatically for fields stored separately, so this code works even without manually adding Hashable and Equatable implementations like in Marek Gregor's answer:
struct Pair<T: Hashable, U: Hashable>: Hashable {
let first: T
let second: U
}
No need special code or magic numbers to implement Hashable
Hashable in Swift 4.2:
struct PairKey: Hashable {
let first: UInt
let second: UInt
func hash(into hasher: inout Hasher) {
hasher.combine(self.first)
hasher.combine(self.second)
}
static func ==(lhs: PairKey, rhs: PairKey) -> Bool {
return lhs.first == rhs.first && lhs.second == rhs.second
}
}
More info: https://nshipster.com/hashable/
I created this code in an app:
struct Point2D: Hashable{
var x : CGFloat = 0.0
var y : CGFloat = 0.0
var hashValue: Int {
return "(\(x),\(y))".hashValue
}
static func == (lhs: Point2D, rhs: Point2D) -> Bool {
return lhs.x == rhs.x && lhs.y == rhs.y
}
}
struct Point3D: Hashable{
var x : CGFloat = 0.0
var y : CGFloat = 0.0
var z : CGFloat = 0.0
var hashValue: Int {
return "(\(x),\(y),\(z))".hashValue
}
static func == (lhs: Point3D, rhs: Point3D) -> Bool {
return lhs.x == rhs.x && lhs.y == rhs.y && lhs.z == rhs.z
}
}
var map : [Point2D : Point3D] = [:]
map.updateValue(Point3D(x: 10.0, y: 20.0,z:0), forKey: Point2D(x: 10.0,
y: 20.0))
let p = map[Point2D(x: 10.0, y: 20.0)]!
If you don't mind a bit of inefficiency, you can easily convert your tuple to a string and then use that for the dictionary key...
var dict = Dictionary<String, SKShapeNode>()
let tup = (3,4)
let key:String = "\(tup)"
dict[key] = ...
You can't yet in Swift 5.3.2, But you can use an Array instead of tuple:
var dictionary: Dictionary<[Int], Any> = [:]
And usage is simple:
dictionary[[1,2]] = "hi"
dictionary[[2,2]] = "bye"
Also it supports any dimentions:
dictionary[[1,2,3,4,5,6]] = "Interstellar"
I suggest to implement structure and use solution similar to boost::hash_combine.
Here is what I use:
struct Point2: Hashable {
var x:Double
var y:Double
public var hashValue: Int {
var seed = UInt(0)
hash_combine(seed: &seed, value: UInt(bitPattern: x.hashValue))
hash_combine(seed: &seed, value: UInt(bitPattern: y.hashValue))
return Int(bitPattern: seed)
}
static func ==(lhs: Point2, rhs: Point2) -> Bool {
return lhs.x == rhs.x && lhs.y == rhs.y
}
}
func hash_combine(seed: inout UInt, value: UInt) {
let tmp = value &+ 0x9e3779b97f4a7c15 &+ (seed << 6) &+ (seed >> 2)
seed ^= tmp
}
It's much faster then using string for hash value.
If you want to know more about magic number.
Add extension file to project (View on gist.github.com):
extension Dictionary where Key == Int64, Value == SKNode {
func int64key(_ key: (Int32, Int32)) -> Int64 {
return (Int64(key.0) << 32) | Int64(key.1)
}
subscript(_ key: (Int32, Int32)) -> SKNode? {
get {
return self[int64key(key)]
}
set(newValue) {
self[int64key(key)] = newValue
}
}
}
Declaration:
var dictionary: [Int64 : SKNode] = [:]
Use:
var dictionary: [Int64 : SKNode] = [:]
dictionary[(0,1)] = SKNode()
dictionary[(1,0)] = SKNode()
Or just use Arrays instead. I was trying to do the following code:
let parsed:Dictionary<(Duration, Duration), [ValveSpan]> = Dictionary(grouping: cut) { span in (span.begin, span.end) }
Which led me to this post. After reading through these and being disappointed (because if they can synthesize Equatable and Hashable by just adopting the protocol without doing anything, they should be able to do it for tuples, no?), I suddenly realized, just use Arrays then. No clue how efficient it is, but this change works just fine:
let parsed:Dictionary<[Duration], [ValveSpan]> = Dictionary(grouping: cut) { span in [span.begin, span.end] }
My more general question becomes "so why aren't tuples first class structs like arrays are then? Python pulled it off (duck and run)."
struct Pair<T:Hashable> : Hashable {
let values : (T, T)
init(_ a: T, _ b: T) {
values = (a, b)
}
static func == (lhs: Pair<T>, rhs: Pair<T>) -> Bool {
return lhs.values == rhs.values
}
func hash(into hasher: inout Hasher) {
let (a, b) = values
hasher.combine(a)
hasher.combine(b)
}
}
let myPair = Pair(3, 4)
let myPairs: Set<Pair<Int>> = set()
myPairs.update(myPair)