struct node
{
int val;
node* next;
};
//此處需要注意,如果寫成void create(node* head,int n)
//這樣即使建立了連結清單,也沒有作用,因為node* head是形參
//在函數内部是對這個指針的拷貝進行操作,故不傳回連結清單
//正确形式應該是void create(node* &head,int n)
node* create(unsigned int n)
{
node *head = new node;
node *p = head, *q;
head->val = rand() % RAND_MAX;
cout << "建立節點:" << 0 << " 值:" << head->val << endl;
for (size_t i = 1; i < n; i++)
{
q = new node;
q->val = rand() % RAND_MAX;
cout << "建立節點:" << i << " 值:" << q->val << endl;
p->next = q; //連結清單疊加
p = p->next;
}
p->next = NULL; //切記尾端處理
return head;
}
void erase(node* head)
{
if (NULL == head) return;
node *tmp;
while (head)
{
tmp = head;
head = head->next;
delete tmp;
}
}
int getnodelen(node* head)
{
int n = 0;
node *temp=head;
while (temp)
{
n++;
temp = temp->next;
}
return n;
}
//此題原本做法出現兩處錯誤
//(1)void delnode(node* head, int num),此處head傳遞進入的是指針的拷貝,如果頭節點被改變,就呵呵了
//(2)邏輯錯誤,原程式中隻若是頭節點相等,删除操作後就傳回了,這種考慮是不完全的
void delnode(node* &head, int num)
{
if (NULL == head) return;
node *temp, *p = head;
//删除從頭節點連續相等數值
while (head != NULL&&head->val == num)
{
temp = head;
head = head->next;
delete temp;
cout << "删除頭節點,數值為:" << num << endl;
}
if (head) p = head;
else return;
while (p->next)
{
if (p->next->val == num)
{
temp = p->next;
//錯誤寫成p = temp->next;
p->next = temp->next;
delete temp;
cout << "删除節點,數值為:" << num << endl;
}
else
{
p = p->next;
}
}
}
//在連結清單中第i個位置插入節點,即在第i個節點前插入元素
bool insert_n_list(node* &head, int n, int num)
{
if (n < 1 || head == NULL) return false;
int i = 1;
node *temp, *p = head;
//插入頭節點
if (n == 1)
{
temp = new node;
temp->val = num;
temp->next = head;
head = temp;
return true;
}
while (p != NULL&&i < n - 1)
{
++i;
p = p->next;
}
if (i == n - 1 && p != NULL) //尋找到插入節點
{
temp = new node;
temp->val = num;
temp->next = p->next;
p->next = temp;
return true;
}
else
{
return false;
}
}
void printnodelist(node* head)
{
if (NULL == head) return;
node *temp = head;
while (temp)
{
cout << " " << temp->val << "," ;
temp = temp->next;
}
cout << endl;
}
//按升序排列(僅進行值交換,不進行指針交換)
void sort_nodelist(node* head)
{
if (head == NULL || head->next == NULL)
return;
node *p = head;
bool sign = false;
int i, j, len = getnodelen(head), temp;
for (i = len - 1; i > 0; i--)
{
sign = false;
p = head;
for ( j = 0; j < i; j++)
{
if (p->val>p->next->val)
{
sign = true;
temp = p->val;
p->val = p->next->val;
p->next->val = temp;
}
p = p->next;
}
if (!sign)
break; //此趟排序未發生交換
}
}
void reverse_nodelist(node* &head)
{
//空連結清單或者單節點連結清單不進行轉置
if (head == NULL || head->next == NULL)
return;
node *p1 = head, *p2 = head->next, *p3;
while (p2)
{
p3 = p2->next;
p2->next = p1;
p1 = p2;
p2 = p3;
}
//此處需注意最後一個節點是NULL,隻有當P2為NULL時,轉置方才完成
//此時将NULL,即P2後面的P1提取出來作為頭節點,轉置完成
head->next = NULL;
head = p1;
}
2015年8月5号添加:
//可以調用遞歸做,但是如果連結清單較長,易導緻棧溢出
void print_reverse(node* list)
{
if (NULL == list)
return;
//單節點單獨處理
if (NULL == list->next)
{
cout << " " << list->val << endl;
return;
}
node* temp;
stack<int> print;
while (NULL != temp)
{
print.push(temp->val);
temp = temp->next;
}
int val;
while (!print.empty()) //stack若為空,用empty判斷傳回true
{
val = print.top();
cout << " " << val << ",";
print.pop();
}
cout << endl;
}
轉載于:https://www.cnblogs.com/jason1990/p/4702422.html