defunorderedSearch(head,target):curNode=headwhilecurNodeisnotNoneandcurNode.data!=target:curNode=curNode.nextreturncurNodeisnotNone# None이 아니면 True반환, 반대면 False반환
answer=unorderedSearch(head,36)print(answer)# True 출력
# Prepending a node to the linked list(값 넣기)
item=1newNode=ListNode(item)newNode.next=head# 서로 값 바꾸기
head=newNode# 서로 값 바꾸기
print(head.data)# 방금 넣은 데이터 1 출력
tail로 넣게 되는것
# Using a tail Node(Appending)
tail=head.next.next.next.next# 마지막 데이터 임의로 접근해서 tail로 만든것이다.
newNode=ListNode(21)# 추가할게 21이다.
tail.next=newNode# 참조를 먼저해서 21을 추가해주고
tail=newNode# tail이 21로 바뀐다.
print(tail.data)# 방금 넣은 21 출력
head, tail 둘다 None일 경우(데이터가 없는 경우겠죠)
# Using a tail Node(Appending) head, tail이 None일 경우
head=Nonetail=NonenewNode=ListNode(21)ifheadisNone:head=newNodeelse:tail.next=newNode# head가 None이 아니라면 바로 마지막을 newNode로 바꿔준다.
tail=newNode
정렬된 링크드 리스트구조에 INSERT하는법
# inserting nodes(정렬된) + 마지막에 넣는 경우와 아무 것도 없는 경우
target=24newNode=ListNode(target)prevNode=NonecurNode=headwhilecurNodeisnotNoneandcurNode.data<target:# target보다 크면 탈출(정렬 특징)
prevNode=curNodecurNode=curNode.nextnewNode.next=curNodeifcurNodeishead:head=newNodeelse:prevNode.next=newNode# curNode = newNode라고 생각하고 해버리면 바로 앞
# newNode를 curNode에 참조(next)하였기 때문에 전에 입력받은
# curNode(target보다 큰 값)의 값만 남는다. 따라서 연결이 되어 있지 않다.
Removing(삭제)
head만 생각했을때
# Removing Nodes(제거하기)
preNode=None# 처음에는 이전 노드가 없기 때문
curNode=headtarget=13whilecurNodeisnotNoneandcurNode.data!=target:preNode=curNodecurNode=curNode.nextifcurNodeisnotNone:ifcurNodeishead:# 처음에 값 있을 때
head=curNode.nextelse:# 다른경우에 값 있을 때
preNode.next=curNode.next# 값 없애기
head, tail 둘다 고려할때
# Using a tail Node(Removing)
# tail과 head가 독립적으로 이용된다. 마지막(tail)이 현재의 값으로 제거 될 때 tail도 한개 줄어든다.
tail=head.next.next.next.next# head는 위에 이미 초기화 되어있고, tail도 초기화 되었다 가정.
preNode=None# 처음에는 이전 노드가 없기 때문
curNode=headtarget=13# 삭제할 데이터
whilecurNodeisnotNoneandcurNode.data!=target:preNode=curNodecurNode=curNode.nextifcurNodeisnotNone:ifcurNodeishead:# 처음일 때
head=curNode.nextelse:# 다른 경우에 값 있을 때
preNode.next=curNode.next# 값 없애기
ifcurNodeistail:tail=preNode# tail 바꿔주기
2. Polynomials(다항식 계산)
# Polynomials(다항식) with Linked 구조
# Term(항), Coefficient(계수), Degree(차수)
# head:차수, tail:계수
classPolyTermNode(object):# 항
def__init__(self,degree,coefficient):self.degree=degreeself.coefficient=coefficientself.next=None
classPolynomial:# 다항식
def__init__(self,degree=None,coefficient=None):# None으로 초기화 해둠
ifdegreeisNone:# coef가 None이여야 None 아닌가?
self.polyHead=Noneelse:self.polyHead=PolyTermNode(degree,coefficient)# 항만들기
self.polyTail=self.polyHeaddefappendTerm(self,degree,coefficient):# 맨 뒤에 추가ok
ifcoefficient!=0.0:# 계수 0 아닐때!!
newTerm=PolyTermNode(degree,coefficient)ifself.polyHeadisNone:self.polyHead=newTermelse:self.polyTail.next=newTerm# head.next도 가능?
self.polyTail=newTermdefdegree(self):# 최고 높은 차수의 항만 선택해서 차수값을 반환하면 됨
ifself.polyHeadisNone:return-1# -1은 무엇??
else:returnself.polyHead.degree# ok
defgetitem(self,degree):# 원하는 차수 구하기
#assert
curNode=self.polyHeadwhilecurNodeisnotNoneandcurNode.degree>=degree:prevNode=curNodecurNode=curNode.nextifprevNodeisNoneorprevNode.degree!=degree:return0.0else:returnprevNode.degreedefevaluate(self,scalar):# 계산하기 ok
#assert
result=0.0# 합은 0으로 초기화, 곱은 1로 초기화를 많이 함.
curNode=self.polyHeadwhilecurNodeisnotNone:result+=curNode.coefficient*(scalar**curNode.degree)curNode=curNode.nextreturnresultdefmultiply(self,rhsPoly):# 곱하기
totalPoly=Polynomial()# 전체 합산 할 다항식 만들기.
nodeA=self.polyHead# poly1다항식의 head노드
whilenodeAisnotNone:# outer loop
newPoly=Polynomial()# 새로운 다항식 만들기
nodeB=rhsPoly.polyHead# poly2다항식의 head노드
whilenodeBisnotNone:# inner loop
newDegree=nodeA.degree+nodeB.degreenewCoeff=nodeA.coefficient*nodeB.coefficientnewPoly.appendTerm(newDegree,newCoeff)nodeB.next# 전체 식에 합산
# totalPoly == None if totalPoly.add(newPoly) else totalPoly = newPoly
if(totalPoly!=None):totalPoly.add(newPoly)else:totalPoly=newPolynodeA.nextreturntotalPolydefadd(self,rhsPoly):# 더하기
newPoly=Polynomial()nodeA=self.polyHead# 수정(하나의 노드를!! 초기화)
nodeB=rhsPoly.polyHead# 수정
whilenodeAisnotNoneandnodeBisnotNone:ifnodeA.degree>nodeB.degree:degree=nodeA.degreevalue=nodeA.coefficientnodeA=nodeA.nextelifnodeA.degree<nodeB.degree:degree=nodeB.degreevalue=nodeB.coefficientnodeB=nodeB.nextelse:degree=nodeA.degreevalue=nodeA.coefficient+nodeB.coefficientnodeA=nodeA.nextnodeB=nodeB.nextnewPoly.appendTerm(degree,value)whilenodeAisnotNone:self.appendTerm(nodeA.degree,nodeA.coefficient)newPoly=nodeA.nextwhilenodeBisnotNone:self.appendTerm(nodeB.degree,nodeB.coefficient)newPoly=nodeB.nextreturnnewPolydefsubstraction(self,rhsPoly):# 빼기
newPoly=Polynomial()nodeA=self.polyHeadnodeB=rhsPoly.polyHeadwhilenodeAisnotNoneandnodeBisnotNone:ifnodeA.degree>nodeB.degree:# nodeA 차수 더크면 그대로 내려옴(0빼서)
degree=nodeA.degreevalue=nodeA.coefficientnodeA=nodeA.nextelifnodeA.degree<nodeB.degree:# nodeA 차수 작으면 계수에 (-)붙어서 내려옴
degree=nodeB.degreevalue=nodeB.coefficient*(-1)nodeB=nodeB.nextelse:# 차수 같을시
if(nodeA.coefficient!=nodeB.coefficient):# A-B가 0이 아닌경우
degree=nodeA.degreevalue=nodeA.coefficient-nodeB.coefficientelif(nodeA.coefficient==0):# A항 없을시
degree=nodeB.degreevalue=nodeB.coefficient*(-1)nodeB=nodeB.nextnodeA=nodeA.nextnewPoly.appendTerm(degree,value)whilenodeAisnotNone:self.appendTerm(nodeA.degree,nodeA.coefficient)newPoly=nodeA.nextwhilenodeBisnotNone:self.appendTerm(nodeB.degree,nodeB.coefficient*(-1))newPoly=nodeB.nextreturnnewPoly# def multiply(self, rhsPoly): # 곱하기
# nodeA = self.polyHead
# totalPoly = Polynomial()
# while nodeA is not None:
# tempPoly = rhsPoly.termMultiply(nodeA) # 함수곱
# totalPoly = totalPoly.add(tempPoly)
# nodeA = nodeA.next
# return totalPoly
# def termMultiply(self, termNode):
# newPoly = Polynomial() # 맞나?
# curr = termNode.next
# while curr is not None:
# newDegree = curr.degree + termNode.degree
# newCoeff = curr.coefficient*termNode.coefficient
# newPoly.appendTerm(newDegree, newCoeff)
# curr = curr.next # 맞나?
# return newPoly
계산
# 자유롭게 숫자 기입할것.
# evaluate 계산 @@!#@#@#(항 뿐만아니라 다항식도 계산!!)
print(Polynomial(2,5).evaluate(5))# 계산@@@@@!!!!!
# append!@!@!@!!!
Poly1=Polynomial(2,5)Poly1.appendTerm(1,3)print(Poly1.polyTail.coefficient)# degree() 최고 차항구하는 것.(head추출 하면 됨)
Poly1=Polynomial(5,5)Poly1.appendTerm(3,3)print(Poly1.degree())# getitem !!@!@ prevNode로 수정 했다~!
Poly1=Polynomial(2,5)Poly1.appendTerm(1,3)print(Poly1.getitem(1))# Poly1에 5x^2 + 3x^1 을 만들고 Poly2에도 똑같이 만들어서 더합니다.
Poly1=Polynomial(2,5)Poly1.appendTerm(1,3)Poly2=Polynomial(2,4)Poly2.appendTerm(1,2)# 다항식을 더해서 newPoly에 저장합니다.
newpoly=Poly1.add(Poly2)psum=newpoly.evaluate(1)# 더한값에 x=1을 해서 계산해줍니다.
print(psum)# 예상값 : 10x^2+6x^1 (x=1이면) = 10+6 = 16
3. Doubly Linked List(이중 연결리스트)
next, prev 둘다 사용하는것이 이중 연결 리스트의 특징이다.
# 이중 연결 리스트
classDListNode:def__init__(self,data):self.data=dataself.next=Noneself.prev=NoneclassDoubleLinkedList:def__init__(self):self.head=Noneself.tail=Noneself.probe=None# tail 이용한 순회
defrevTraversal(self):curNode=self.tailwhilecurNodeisnotNone:print(curNode.data)curNode=curNode.prev# Searching 간단 -생략
defrevSearching(self,target):ifself.headisNone:returnFalseelifself.probeisNone:# probe 초기화 시켜주기
probe=self.headiftarget<probe.data:whileprobeisnotNoneandtarget<=probe.data:iftarget==probe.data:returnTrueelse:probe=probe.prevelse:whileprobeisnotNoneandtarget>=probe.data:iftarget==probe.data:returnTrueelse:probe=probe.nextreturnFalse# add
defrevAdding(self,value):newnode=DListNode(value)ifself.headisNone:self.head=newnodeself.tail=self.headelifvalue<self.head.data:newnode.next=self.headself.head.prev=newnodeself.head=newnodeelifvalue>self.tail.data:newnode.prev=self.tailself.tail.next=newnodeself.tail=newnodeelse:node=self.headwhilenodeisnotNoneandnode.data<value:node=node.nextnewnode.next=nodenewnode.prev=node.prevnode.prev.next=newnodenode.prev=newnodereturnnewnode.data# 리턴은 자유~!
# remove -> 생략
DList=DoubleLinkedList()DList.revAdding(5)DList.revAdding(3)DList.revAdding(2)DList.revTraversal()# 5,3,2
print(DList.revSearching(2))# True
4. Circular Linked List(원형 연결리스트)
단순, 이중 연결리스트에서 모두 구현 가능하다.
노드간의 연결의 끝부분들이 원형처럼 각 반대쪽의 끝부분과 연결이 되어있는 형태이다.
# 원형 연결 리스트
classCListNode:def__init__(self,data):self.data=dataself.next=NoneclassCircleLinkedList:def__init__(self):self.head=Noneself.listRef=None# 순회
deftraverse(self):curNode=self.listRefdone=self.listRefisNonewhilenotdone:curNode=curNode.nextprint(curNode.data)done=curNodeisself.listRef# 검색
defsearch(self,target):curNode=self.listRefdone=self.listRefisNonewhilenotdone:curNode=curNode.nextifcurNode.data==target:returnTrueelse:done=curNodeisself.listReforcurNode.data>targetreturnFalse# 추가
defAdding(self,value):newNode=CListNode(value)ifself.listRefisNone:# empty list
self.listRef=newNodenewNode.next=newNodeelifvalue<self.listRef.next.data:# insert in front
newNode.next=self.listRef.nextself.listRef.next=newNodeelifvalue>self.listRef.next.data:# insert in back
newNode.next=self.listRef.nextself.listRef.next=newNodeself.listRef=newNodeelse:# insert in middle
predNode=NonecurNode=self.listRefdone=self.listRefisNonewhilenotdone:predNode=curNodecurNode=curNode.nextdone=curNodeisself.listReforcurNode.data>valuenewNode.next=curNodepredNode.next=newNode# remove -> 생략
CList=CircleLinkedList()CList.Adding(5)CList.Adding(4)CList.Adding(30)CList.traverse()# 4,,5,30
print(CList.search(1))# False
5. Multi Linked List(멀티 연결리스트)
예를들어 next로 노드끼리 연결하는데, 다음 노드 뿐만아니라 다른 노드에도 연결하는 형태이다.
EX) SparseMatrix(희소 매트릭스) : 행, 열이 필요하기 때문에 이를 다중 연결 리스트 만으로도 구현이 가능한 것이다.(MLL)
그러나 만약 단일 연결 리스트로만 구현하고 싶다면(SLL) 리스트 - 연결리스트 형태로 행과 열을 구분해서 구현이 가능하다는점을 참고하자.
Chains(복수의 키를 생성하기 위해), Chain은 목적에 따라 다양하게 생성할 수 있음
우리가 기본으로 알던건 SLL(Singly Linked List)인것이고, 이것은 MLL(Multi Linked List)이다.
SLL : 좌, 우 연결만 생각
MLL : 상, 하, 좌, 우 연결만 생각
# 희소 매트릭스에는 연결리스트 구조로 해결하는것이 좋다.
# SLL이나 MLL 방식 둘다 구현 가능하다.
# 만들다가 말았던 상태라, 아래 코드는 절대 구동이 되는건 아니고 궁금하다면 인터넷 서핑을 이용해 수정해보자.
# 희소 매트릭스 MLL(멀티 연결 리스트)
classMatrixMListNode:def__init__(self,row,col,value):self.row=rowself.col=colself.value=value# self.curRow = 0
# self.curCol = 0
self.nextCol=Noneself.nextRow=NonedeffindNextElement(self):i=self.curRowwhilei<len(self.rowArray)andself.rowArray[i]isNone:i+=1self.curRow=iifi<len(self.rowArray):self.curNode=self.rowArray[i]else:self.curNode=None# 희소 매트릭스 SLL(단일) -> 멀티 연결리스트가 아니라 단일 연결리스트임
classSparseMatrixIterator:def__init__(self,rowArray):self.rowArray=rowArrayself.curRow=0self.curNode=Noneself.findNextElement()def__iter__(self):returnselfdefnext(self):ifself.curNodeisNone:raiseStopIterationelse:value=self.curNode.valueself.curNode=self.curNode.nextifself.curNodeisNone:self.findNextElement()returnvaluedeffindNextElement(self):i=self.curRowwhilei<len(self.rowArray)andself.rowArray[i]isNone:i+=1self.curRow=iifi<len(self.rowArray):self.curNode=self.rowArray[i]else:self.curNode=None
댓글남기기