链表的常见操作
2012-03-17 16:59
274 查看
一、链表创建
链表主要有三种形式,包括单链表、双链表和循环链表。单链表每个节点只包含一个后驱指针,双链表节点同时包含一个前驱指针和一个后驱指针,循环链表的尾节点的后驱指向头节点。
/*单链表节点结构*/ typedef struct NodeType { char elem; NodeType*next; }Node; /*双链表节点结构*/ typedef struct DNodeType { char elem; DNodeType*next; DNodeType*prev; }DNode;
单链表的创建
/*创建链表*/ Node* CreateList(Node* head) { if(NULL == head)//分配头节点空间 head = (Node*)malloc(sizeof(Node)), head->next = NULL; Node*current = head ,*temp; char ch; while(1) { cout << ”\n input elem:”; cin >> ch; if(‘#’ == ch)/*#结束输入*/ break; temp = (Node*) malloc (sizeof(Node) ); temp->elem = ch; temp->next = NULL; current->next = temp;/*当前节点的后驱指向新节点*/ current = temp;/*当前节点为链表尾节点*/ } return head; }
双向链表的创建
/*创建双向链表*/ DNode* DoubleList(DNode* head) { if(NULL== head)//分配头节点空间 head=(DNode*)malloc(sizeof(DNode)) , head->prev=NULL , head->next=NULL; DNode*current=head ,*temp; char ch; while(1) { cout<<”\n input elem:”; cin>>ch; if(‘#’ == ch)/*#结束输入*/ break; temp=(DNode*) malloc (sizeof(DNode) ); temp->elem=ch; temp->next=NULL; current->next=temp;/*当前节点的后驱指向新节点*/ temp->prev=current;/*新节点的前驱指向当前节点*/ current=temp;/*当前节点为链表尾节点*/ } return head; }
二、链表的操作
添加节点
/*单链表,在链表尾部插入节点*/ Node* InsertNode(Node* head ,char elem) { if( NULL== head|| NULL== elem ) return head; Node* current=head->next;/*当前节点*/ Node* prev=head;/*前驱节点*/ Node* temp;/*过渡节点*/ while(current)/*移动至尾节点*/ { prev=current; current=current->next; } temp=(Node*) malloc(sizeof(Node) ); temp->elem=elem; temp->next=NULL; prev->next=temp;/*尾节点的后驱指向新节点*/ return head; }
三、单链表逆转
算法描述:将链表中每一个节点插入到头结点之后。/*单链表逆置*/ Node* ReverseList(Node* head) { if(NULL== head) return head; if(NULL== head->next) return head; if(NULL== head->next->next) return head; Node*curr=head->next;/*当前节点*/ head->next=NULL; Node*temp; while(curr) { temp=curr->next;/*暂存下一个节点*/ /*把当前节点插入到head节点后*/ curr->next=head->next; head->next=curr; curr=temp;/*移动至下一个节点*/ } return head; }
四、求单链表的中间节点
算法描述:设立两个指针p1,p2,p1每次移动1个节点位置,p2每次移动2个节点位置,当p2移动到尾节点时,p1指向中间节点。/*求中间节点*/ Node* MiddleNode(Node* head) { if(NULL== head) return head; if(NULL== head->next) return head->next; Node *p1,*p2; p1=head; p2=head; while(p2->next) { /*p2节点移动2个节点位置*/ p2=p2->next; if(p2->next)/*判断p2后驱节点是否存在,存在则再移动一次*/ p2=p2->next; /*p1节点移动1个节点位置*/ p1=p1->next; } return p1; }
五、合并有序单链表
问题描述:合并2个有序单链表,合并后的链表也是排好序的。算法描述:对链表A中的每一个节点元素,查找其在链表B中的插入位置,并在B中插入该元素。
/*合并有序单链表*/ Node* MergeList(Node* h1,Node* h2) { if(NULL== h1|| NULL== h2) return h1; if(NULL== h1->next ) return h2; if(NULL== h2->next) return h1; Node* curr1,*curr2,*prev1,*temp; prev1=h1;/*链表1的前驱节点*/ curr1=h1->next;/*链表1的当前节点*/ curr2=h2->next;/*链表2的当前节点*/ temp=h2; while(curr2) { while(curr1&& curr1->elem< curr2->elem)/*链表1指针移动至大或等于链表2当前元素的位置*/ prev1=curr1,curr1=curr1->next; /*在链表1中插入链表2的当前元素*/ temp=curr2->next;/*暂存链表2的下一个节点*/ prev1->next=curr2; curr2->next=curr1; /*链表1移动至新节点*/ curr1=curr2; /*链表2移动至下一个节点*/ curr2=temp; } return h1; }