如何从链接列表中删除第n个元素?
import Data.List
data LinkedList = LLEmpty | LLNode Int LinkedList deriving (Eq, Show, Ord)
在第n个位置插入一个整数
linkListInsertNPosition :: Int -> Int -> LinkedList -> LinkedList
linkListInsertNPosition pos val listL =
let ninsertion = insertionN val (lengthL listL - pos) listL
in ninsertion
insertionN :: Int -> Int -> LinkedList -> LinkedList
insertionN val count listL =
case listL of
LLEmpty -> LLEmpty
(LLNode a b) -> if (count <=0)
then LLNode val (LLNode a b)
else LLNode a (insertionN val (count - 1) b)
最后,链接列表的尾部和头部
lastL :: LinkedList -> Int
lastL listL =
case listL of
LLNode a b -> a
tailL :: LinkedList -> LinkedList
tailL listL =
case listL of
LLEmpty -> LLEmpty
LLNode a b -> b
headL :: LinkedList -> Int --100
headL listL =
case listL of
LLNode a LLEmpty -> a
LLNode a b -> headL (tailL b)
获取链表的长度
lengthL :: LinkedList -> Int
lengthL listL =
case listL of
LLEmpty -> 0
LLNode a b -> 1 + (lengthL (tailL listL))
我一直在删除链接列表中的第n个元素。任何人都可以帮助我并建议一种方式。 删除第n个元素后如何加入链接列表?或者我需要做一个新的链接列表?
答案 0 :(得分:2)
链接列表LList
是Empty
或包含值和另一个链接列表。
data LList a = Empty | Node a LList
如果我们为内置(:)
链接列表定义一个运算符(如[]
),这可能会更容易
data LList a = Empty | a :+: LList
-- much like:
-- data [a] = [] | a : [a]
您的列表具体为Int
s,因此我们可以删除多态性
data LList = Empty | Int :+: LList
deriving (Eq, Show, Ord)
-- and, useful for testing:
fromList :: [Int] -> LList
fromList = foldr (:+:) Empty
在n
之后插入只是推送链接列表n
次并在此时重新链接。
import Data.Either (partitionEithers)
-- partitionEithers :: [Either a b] -> ([a], [b])
-- fun fact, I had to look this one up, but this is how haskell implements (++)
(|++|) :: LList -> LList -> LList
Empty |++| ys = ys
xs |++| Empty = xs
(x:+:xs) |++| ys = x :+: (xs |++| ys)
mySplitAt :: Int -> LList -> (LList, LList)
mySplitAt n = partitionEithers . map (go n) . zip [0..]
where
go n (i, x) | i < n = Left x
| otherwise = Right x
insertAfter :: Int -> Int -> LList -> LList
insertAfter n x xs = before |++| (x :+: after)
where (before, after) = mySplitAt n xs
这意味着删除第n个值只是在特定节点之后重新链接
delete :: Int -> LList -> LList
delete n xs = before |++| after
where (before, _ :+: after) = mySplitAt n xs
答案 1 :(得分:1)
也许这会给你一些想法
Prelude> let removeAt n = map snd . filter ((/=n) . fst) . zip [1..]
Prelude> removeAt 3 [1..10]
[1,2,4,5,6,7,8,9,10]
要么可以递归计算位置,要么使用zip
添加索引并处理该索引。
答案 2 :(得分:0)
你可以这样做。
removeNth :: Int -> [a] -> [a]
removeNth n ls = let (pref, suff) = splitAt n ls
in pref ++ (tail suff)